mirror of
https://github.com/openharmony/third_party_openhitls.git
synced 2026-07-01 10:05:26 -04:00
!41 merge master into master
add sha256-mb interfaces
Created-by: Dongjianwei001
Commit-by: jchx;Dongjianwei001;dumb
Merged-by: openharmony_ci
Description: ### 一、内容说明(相关的Issue)
### 二、建议测试周期和提测地址
建议测试完成时间:xxxx.xx.xx
投产上线时间:xxxx.xx.xx
提测地址:CI环境/压测环境
测试账号:
### 三、变更内容
* 3.1 关联PR列表
* 3.2 数据库和部署说明
1. 常规更新
2. 重启unicorn
3. 重启sidekiq
4. 迁移任务:是否有迁移任务,没有写 "无"
5. rake脚本:`bundle exec xxx RAILS_ENV = production`;没有写 "无"
* 3.4 其他技术优化内容(做了什么,变更了什么)
- 重构了 xxxx 代码
- xxxx 算法优化
* 3.5 废弃通知(什么字段、方法弃用?)
* 3.6 后向不兼容变更(是否有无法向后兼容的变更?)
### 四、研发自测点(自测哪些?冒烟用例全部自测?)
自测测试结论:
### 五、测试关注点(需要提醒QA重点关注的、可能会忽略的地方)
检查点:
| 需求名称 | 是否影响xx公共模块 | 是否需要xx功能 | 需求升级是否依赖其他子产品 |
|------|------------|----------|---------------|
| xxx | 否 | 需要 | 不需要 |
| | | | |
接口测试:
性能测试:
并发测试:
其他:
See merge request: openharmony/third_party_openhitls!41
This commit is contained in:
@@ -147,6 +147,7 @@ public_all_defines = [
|
||||
"HITLS_CRYPTO_MLDSA",
|
||||
"HITLS_CRYPTO_SLH_DSA",
|
||||
"HITLS_CRYPTO_SM2_PRECOMPUTE_512K_TBL",
|
||||
"HITLS_CRYPTO_SHA2_MB",
|
||||
"HITLS_PKI",
|
||||
"HITLS_PKI_INFO",
|
||||
"HITLS_PKI_PKCS12",
|
||||
|
||||
@@ -54,6 +54,11 @@
|
||||
},
|
||||
"sha3": null
|
||||
},
|
||||
"md_mb": {
|
||||
"sha2_mb": {
|
||||
"sha256_mb": null
|
||||
}
|
||||
},
|
||||
"mac": {
|
||||
"hmac": null,
|
||||
"gmac": {"deps": ["eal", "aes", "gcm"]},
|
||||
@@ -709,7 +714,7 @@
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"sha2": {
|
||||
".features": ["sha224", "sha256", "sha384", "sha512"],
|
||||
".features": ["sha224", "sha256", "sha384", "sha512", "sha2_mb"],
|
||||
".srcs": {
|
||||
"public": "crypto/sha2/src/sha2*.c",
|
||||
"no_asm": "crypto/sha2/src/noasm_*.c",
|
||||
|
||||
@@ -752,6 +752,30 @@
|
||||
#define HITLS_CRYPTO_SM3_ASM
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_MD_MB
|
||||
#ifndef HITLS_CRYPTO_SHA2_MB
|
||||
#define HITLS_CRYPTO_SHA2_MB
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_SHA2_MB
|
||||
#ifndef HITLS_CRYPTO_SHA256_MB
|
||||
#define HITLS_CRYPTO_SHA256_MB
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_SHA256_MB)
|
||||
#ifndef HITLS_CRYPTO_SHA2_MB
|
||||
#define HITLS_CRYPTO_SHA2_MB
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_SHA2_MB)
|
||||
#ifndef HITLS_CRYPTO_MD_MB
|
||||
#define HITLS_CRYPTO_MD_MB
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_BN_X8664) || defined(HITLS_CRYPTO_BN_ARMV8)
|
||||
#define HITLS_CRYPTO_BN_ASM
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "crypt_errno.h"
|
||||
#include "eal_md_local.h"
|
||||
#include "eal_common.h"
|
||||
#include "crypt_utils.h"
|
||||
#include "crypt_ealinit.h"
|
||||
#ifdef HITLS_CRYPTO_PROVIDER
|
||||
#include "crypt_eal_implprovider.h"
|
||||
@@ -440,4 +441,121 @@ int32_t CRYPT_EAL_Md(CRYPT_MD_AlgId id, const uint8_t *in, uint32_t inLen, uint8
|
||||
{
|
||||
return EAL_Md(id, in, inLen, out, outLen);
|
||||
}
|
||||
|
||||
#ifdef HITLS_CRYPTO_MD_MB
|
||||
|
||||
CRYPT_EAL_MdCTX *CRYPT_EAL_MdMBNewCtx(CRYPT_EAL_LibCtx *libCtx, int32_t id, uint32_t num)
|
||||
{
|
||||
(void)libCtx;
|
||||
if (UNLIKELY(num == 0)) {
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_NULL_INPUT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAL_MdMBMethod mbMethod = {0};
|
||||
if (EAL_MdFindMbMethod(id, &mbMethod) == NULL ||
|
||||
mbMethod.newCtx == NULL || mbMethod.freeCtx == NULL) {
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_NOT_SUPPORT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *mbData = mbMethod.newCtx(num);
|
||||
if (mbData == NULL) {
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_MEM_ALLOC_FAIL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CRYPT_EAL_MdCTX *ctx = BSL_SAL_Calloc(1, sizeof(CRYPT_EAL_MdCTX));
|
||||
if (ctx == NULL) {
|
||||
mbMethod.freeCtx(mbData);
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_MEM_ALLOC_FAIL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->mbMethod = mbMethod;
|
||||
ctx->data = mbData;
|
||||
ctx->id = id;
|
||||
ctx->state = CRYPT_MD_STATE_NEW;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void CRYPT_EAL_MdMBFreeCtx(CRYPT_EAL_MdCTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
if (ctx->mbMethod.freeCtx != NULL) {
|
||||
ctx->mbMethod.freeCtx(ctx->data);
|
||||
}
|
||||
BSL_SAL_Free(ctx);
|
||||
}
|
||||
|
||||
int32_t CRYPT_EAL_MdMBInit(CRYPT_EAL_MdCTX *ctx)
|
||||
{
|
||||
if (UNLIKELY(ctx == NULL)) {
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
|
||||
CRYPT_MD_AlgId id = ctx->id;
|
||||
if (ctx->mbMethod.init == NULL) {
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_NOT_SUPPORT);
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
}
|
||||
int32_t ret = ctx->mbMethod.init(ctx->data);
|
||||
|
||||
if (ret == CRYPT_SUCCESS) {
|
||||
ctx->state = CRYPT_MD_STATE_INIT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t CRYPT_EAL_MdMBUpdate(CRYPT_EAL_MdCTX *ctx, const uint8_t *data[], uint32_t nbytes[], uint32_t num)
|
||||
{
|
||||
if (UNLIKELY(ctx == NULL || data == NULL || nbytes == NULL || num == 0)) {
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
if (UNLIKELY(nbytes[0] == 0)) {
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
CRYPT_MD_AlgId id = ctx->id;
|
||||
if (ctx->mbMethod.update == NULL) {
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_NOT_SUPPORT);
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
int32_t ret = ctx->mbMethod.update(ctx->data, data, nbytes, num);
|
||||
if (ret == CRYPT_SUCCESS) {
|
||||
ctx->state = CRYPT_MD_STATE_UPDATE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t CRYPT_EAL_MdMBFinal(CRYPT_EAL_MdCTX *ctx, uint8_t *digest[], uint32_t *outlen, uint32_t num)
|
||||
{
|
||||
if (UNLIKELY(ctx == NULL || digest == NULL || outlen == NULL || num == 0)) {
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
|
||||
CRYPT_MD_AlgId id = ctx->id;
|
||||
if (ctx->mbMethod.final == NULL) {
|
||||
EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_NOT_SUPPORT);
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
int32_t ret = ctx->mbMethod.final(ctx->data, digest, outlen, num);
|
||||
if (ret == CRYPT_SUCCESS) {
|
||||
ctx->state = CRYPT_MD_STATE_FINAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // HITLS_CRYPTO_MD_MB
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,11 +38,18 @@ typedef enum {
|
||||
struct EAL_MdCtx {
|
||||
bool isProvider;
|
||||
EAL_MdUnitaryMethod *method; /* algorithm operation entity */
|
||||
#ifdef HITLS_CRYPTO_MD_MB
|
||||
EAL_MdMBMethod mbMethod; /* multi-buffer operation entity */
|
||||
#endif
|
||||
void *data; /* Algorithm ctx, mainly context */
|
||||
uint32_t state;
|
||||
CRYPT_MD_AlgId id;
|
||||
};
|
||||
|
||||
#ifdef HITLS_CRYPTO_MD_MB
|
||||
EAL_MdMBMethod *EAL_MdFindMbMethod(CRYPT_MD_AlgId id, EAL_MdMBMethod *method);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup eal
|
||||
* @brief Method for generating the hash algorithm
|
||||
|
||||
@@ -140,6 +140,46 @@ const EAL_MdMethod *EAL_MdFindMethod(CRYPT_MD_AlgId id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HITLS_CRYPTO_MD_MB
|
||||
#ifdef HITLS_CRYPTO_SHA2_MB
|
||||
static const EAL_MdMBMethod g_mdMbMethod_SHA256 = {
|
||||
(MdMBNewCtx)CRYPT_SHA256_MBNewCtx,
|
||||
(MdMBFreeCtx)CRYPT_SHA256_MBFreeCtx,
|
||||
(MdMBInit)CRYPT_SHA256_MBInit,
|
||||
(MdMBUpdate)CRYPT_SHA256_MBUpdate,
|
||||
(MdMBFinal)CRYPT_SHA256_MBFinal
|
||||
};
|
||||
#endif
|
||||
|
||||
static const EAL_CidToMdMbMeth ID_TO_MD_MB_METH_TABLE[] = {
|
||||
#ifdef HITLS_CRYPTO_SHA2_MB
|
||||
{CRYPT_MD_SHA256_MB, &g_mdMbMethod_SHA256},
|
||||
#endif
|
||||
};
|
||||
|
||||
static const EAL_MdMBMethod *EAL_MdFindDefaultMbMethod(CRYPT_MD_AlgId id)
|
||||
{
|
||||
uint32_t num = sizeof(ID_TO_MD_MB_METH_TABLE) / sizeof(ID_TO_MD_MB_METH_TABLE[0]);
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
if (ID_TO_MD_MB_METH_TABLE[i].id == id) {
|
||||
return ID_TO_MD_MB_METH_TABLE[i].mbMeth;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAL_MdMBMethod *EAL_MdFindMbMethod(CRYPT_MD_AlgId id, EAL_MdMBMethod *method)
|
||||
{
|
||||
const EAL_MdMBMethod *findMethod = EAL_MdFindDefaultMbMethod(id);
|
||||
if (findMethod == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID);
|
||||
return NULL;
|
||||
}
|
||||
*method = *findMethod;
|
||||
return method;
|
||||
}
|
||||
#endif // HITLS_CRYPTO_MD_MB
|
||||
|
||||
int32_t EAL_Md(CRYPT_MD_AlgId id, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
@@ -45,6 +45,22 @@ typedef void (*MdFreeCtx)(void *data);
|
||||
typedef int32_t (*MdCtrl)(void *data, int32_t cmd, void *val, uint32_t valLen);
|
||||
typedef int32_t (*MdSqueeze)(void *data, uint8_t *out, uint32_t len);
|
||||
|
||||
#ifdef HITLS_CRYPTO_MD_MB
|
||||
typedef void *(*MdMBNewCtx)(uint32_t num);
|
||||
typedef void (*MdMBFreeCtx)(void *ctx);
|
||||
typedef int32_t (*MdMBInit)(void *ctx);
|
||||
typedef int32_t (*MdMBUpdate)(void *ctx, const uint8_t *data[], uint32_t nbytes[], uint32_t num);
|
||||
typedef int32_t (*MdMBFinal)(void *ctx, uint8_t *digest[], uint32_t *outlen, uint32_t num);
|
||||
|
||||
typedef struct {
|
||||
MdMBNewCtx newCtx;
|
||||
MdMBFreeCtx freeCtx;
|
||||
MdMBInit init;
|
||||
MdMBUpdate update;
|
||||
MdMBFinal final;
|
||||
} EAL_MdMBMethod;
|
||||
#endif // HITLS_CRYPTO_MD_MB
|
||||
|
||||
typedef struct {
|
||||
uint16_t blockSize; // Block size processed by the hash algorithm at a time, which is used with other algorithms.
|
||||
uint16_t mdSize; // Output length of the HASH algorithm
|
||||
@@ -86,6 +102,13 @@ typedef struct {
|
||||
EAL_MdMethod *mdMeth;
|
||||
} EAL_CidToMdMeth;
|
||||
|
||||
#ifdef HITLS_CRYPTO_MD_MB
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
const EAL_MdMBMethod *mbMeth;
|
||||
} EAL_CidToMdMbMeth;
|
||||
#endif
|
||||
|
||||
/* provide asymmetric primitive method */
|
||||
typedef void *(*PkeyNew)(void);
|
||||
typedef void* (*PkeyProvNew)(void *provCtx, int32_t algId);
|
||||
|
||||
@@ -185,7 +185,6 @@ g_kExt:
|
||||
.global SHA1_Step
|
||||
.type SHA1_Step, %function
|
||||
SHA1_Step:
|
||||
.inst 0xd503233f // paciasp
|
||||
cmp x1, #64
|
||||
b.lo .Lend_sha1
|
||||
|
||||
@@ -454,7 +453,6 @@ SHA1_Step:
|
||||
ldp x29, x30, [sp], #96
|
||||
|
||||
.Lend_sha1:
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size SHA1_Step, .-SHA1_Step
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ extern "C" {
|
||||
#ifdef HITLS_CRYPTO_SHA256
|
||||
#define CRYPT_SHA2_256_BLOCKSIZE 64
|
||||
#define CRYPT_SHA2_256_DIGESTSIZE 32
|
||||
#define CRYPT_SHA256_STATE_SIZE 8
|
||||
#endif // HITLS_CRYPTO_SHA256
|
||||
|
||||
#ifdef HITLS_CRYPTO_SHA384
|
||||
@@ -254,6 +255,153 @@ int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint
|
||||
* @retval #CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH output buffer is not enough
|
||||
*/
|
||||
int32_t CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx *ctx, uint8_t *digest, uint32_t *outlen);
|
||||
|
||||
typedef struct {
|
||||
uint32_t num;
|
||||
CRYPT_SHA2_256_Ctx *ctxs;
|
||||
} CRYPT_SHA2_256_MB_Ctx;
|
||||
|
||||
/**
|
||||
* @ingroup SHA256
|
||||
* @brief Create a SHA256 multi-buffer context.
|
||||
*
|
||||
* Notes:
|
||||
* - Currently only supports num == 2.
|
||||
*
|
||||
* @param num [IN] Number of parallel messages/contexts.
|
||||
*
|
||||
* @retval Pointer to multi-buffer context on success.
|
||||
* @retval NULL on failure (invalid num or memory allocation failure).
|
||||
*/
|
||||
CRYPT_SHA2_256_MB_Ctx *CRYPT_SHA256_MBNewCtx(uint32_t num);
|
||||
|
||||
/**
|
||||
* @ingroup SHA256
|
||||
* @brief Free a SHA256 multi-buffer context.
|
||||
*
|
||||
* @param ctx [IN] Multi-buffer context pointer (can be NULL).
|
||||
*/
|
||||
void CRYPT_SHA256_MBFreeCtx(CRYPT_SHA2_256_MB_Ctx *ctx);
|
||||
|
||||
/**
|
||||
* @ingroup SHA256
|
||||
* @brief Initialize a SHA256 multi-buffer context.
|
||||
*
|
||||
* Notes:
|
||||
* - Currently only supports ctx->num == 2.
|
||||
*
|
||||
* @param ctx [IN/OUT] Multi-buffer context.
|
||||
*
|
||||
* @retval #CRYPT_SUCCESS Success.
|
||||
* @retval #CRYPT_NULL_INPUT ctx is NULL.
|
||||
* @retval #CRYPT_NOT_SUPPORT Not supported (e.g. ctx->num != 2 or platform capability missing).
|
||||
*/
|
||||
int32_t CRYPT_SHA256_MBInit(CRYPT_SHA2_256_MB_Ctx *ctx);
|
||||
|
||||
/**
|
||||
* @ingroup SHA256
|
||||
* @brief Update SHA256 multi-buffer context with message fragments.
|
||||
*
|
||||
* Notes:
|
||||
* - Each update processes one fragment per message, where data[i] is the fragment for lane i.
|
||||
* - nbytes[i] is the fragment length for lane i. Currently requires nbytes[0] == nbytes[1],
|
||||
* otherwise returns #CRYPT_NOT_SUPPORT.
|
||||
* - Currently only supports num == 2.
|
||||
*
|
||||
* @param ctx [IN/OUT] Multi-buffer context.
|
||||
* @param data [IN] Input pointer array. data[i] is fragment pointer for lane i.
|
||||
* @param nbytes [IN] Input length array. nbytes[i] is fragment length for lane i.
|
||||
* @param num [IN] Number of lanes/messages.
|
||||
*
|
||||
* @retval #CRYPT_SUCCESS Success.
|
||||
* @retval #CRYPT_NULL_INPUT Invalid input pointer.
|
||||
* @retval #CRYPT_NOT_SUPPORT Not supported (e.g. num != 2 or per-lane lengths are not equal).
|
||||
* @retval Other error codes, see crypt_errno.h.
|
||||
*/
|
||||
int32_t CRYPT_SHA256_MBUpdate(CRYPT_SHA2_256_MB_Ctx *ctx, const uint8_t *data[], uint32_t nbytes[], uint32_t num);
|
||||
|
||||
/**
|
||||
* @ingroup SHA256
|
||||
* @brief Finalize SHA256 multi-buffer context and output digests.
|
||||
*
|
||||
* Notes:
|
||||
* - Currently only supports num == 2.
|
||||
* - outlen indicates output buffer size on input and returns actual digest length on output.
|
||||
*
|
||||
* @param ctx [IN/OUT] Multi-buffer context.
|
||||
* @param digest [OUT] Digest buffer pointer array. digest[i] is output buffer for lane i.
|
||||
* @param outlen [IN/OUT] Output buffer length / output digest length.
|
||||
* @param num [IN] Number of lanes/messages.
|
||||
*
|
||||
* @retval #CRYPT_SUCCESS Success.
|
||||
* @retval #CRYPT_NULL_INPUT Invalid input pointer.
|
||||
* @retval #CRYPT_NOT_SUPPORT Not supported (e.g. num != 2 or platform capability missing).
|
||||
* @retval Other error codes, see crypt_errno.h.
|
||||
*/
|
||||
int32_t CRYPT_SHA256_MBFinal(CRYPT_SHA2_256_MB_Ctx *ctx, uint8_t *digest[], uint32_t *outlen, uint32_t num);
|
||||
|
||||
/**
|
||||
* @ingroup SHA256
|
||||
* @brief SHA256 dual-lane compression for full blocks.
|
||||
*
|
||||
* This function compresses nblocks full SHA256 blocks for two independent states in parallel.
|
||||
* It does not handle padding or length encoding.
|
||||
*
|
||||
* @param state1 [IN/OUT] SHA256 state for lane 0. Array size is #CRYPT_SHA256_STATE_SIZE.
|
||||
* @param state2 [IN/OUT] SHA256 state for lane 1. Array size is #CRYPT_SHA256_STATE_SIZE.
|
||||
* @param block1 [IN] Input block pointer for lane 0 (must contain nblocks * 64 bytes).
|
||||
* @param block2 [IN] Input block pointer for lane 1 (must contain nblocks * 64 bytes).
|
||||
* @param nblocks [IN] Number of full 64-byte blocks to compress.
|
||||
*/
|
||||
void CRYPT_SHA256x2_Compress(uint32_t state1[CRYPT_SHA256_STATE_SIZE], uint32_t state2[CRYPT_SHA256_STATE_SIZE],
|
||||
const uint8_t *block1, const uint8_t *block2, uint32_t nblocks);
|
||||
|
||||
/**
|
||||
* @ingroup SHA256
|
||||
* @brief SHA256 multi-buffer one-shot hashing.
|
||||
*
|
||||
* Notes:
|
||||
* - Currently only supports num == 2.
|
||||
* - nbytes is the same length for all lanes in this one-shot API.
|
||||
*
|
||||
* @param data [IN] Input pointer array. data[i] is message pointer for lane i.
|
||||
* @param nbytes [IN] Input length in bytes.
|
||||
* @param digest [OUT] Digest buffer pointer array. digest[i] is output buffer for lane i.
|
||||
* @param outlen [IN/OUT] Output buffer length / output digest length.
|
||||
* @param num [IN] Number of lanes/messages.
|
||||
*
|
||||
* @retval #CRYPT_SUCCESS Success.
|
||||
* @retval #CRYPT_NULL_INPUT Invalid input pointer.
|
||||
* @retval #CRYPT_NOT_SUPPORT Not supported (e.g. num != 2 or platform capability missing).
|
||||
* @retval Other error codes, see crypt_errno.h.
|
||||
*/
|
||||
int32_t CRYPT_SHA256_MB(const uint8_t *data[], uint32_t nbytes, uint8_t *digest[], uint32_t *outlen, uint32_t num);
|
||||
|
||||
/**
|
||||
* @ingroup SHA256
|
||||
* @brief SHA256 dual-lane one-shot hashing with initial states.
|
||||
*
|
||||
* This function computes SHA256 digests for two messages in parallel, starting from the provided
|
||||
* SHA256 states.
|
||||
*
|
||||
* Notes:
|
||||
* - This API is intended for internal acceleration paths.
|
||||
*
|
||||
* @param state1 [IN/OUT] SHA256 state for lane 0. Array size is #CRYPT_SHA256_STATE_SIZE.
|
||||
* @param state2 [IN/OUT] SHA256 state for lane 1. Array size is #CRYPT_SHA256_STATE_SIZE.
|
||||
* @param data1 [IN] Input message pointer for lane 0.
|
||||
* @param data2 [IN] Input message pointer for lane 1.
|
||||
* @param nbytes [IN] Input length in bytes for both lanes.
|
||||
* @param dgst1 [OUT] Digest output buffer for lane 0 (size #CRYPT_SHA2_256_DIGESTSIZE).
|
||||
* @param dgst2 [OUT] Digest output buffer for lane 1 (size #CRYPT_SHA2_256_DIGESTSIZE).
|
||||
*
|
||||
* @retval #CRYPT_SUCCESS Success.
|
||||
* @retval #CRYPT_NOT_SUPPORT Not supported on this platform/build.
|
||||
*/
|
||||
int32_t CRYPT_SHA256x2(uint32_t state1[CRYPT_SHA256_STATE_SIZE], uint32_t state2[CRYPT_SHA256_STATE_SIZE],
|
||||
const uint8_t *data1, const uint8_t *data2, uint32_t nbytes,
|
||||
uint8_t dgst1[CRYPT_SHA2_256_DIGESTSIZE], uint8_t dgst2[CRYPT_SHA2_256_DIGESTSIZE]);
|
||||
|
||||
#endif // HITLS_CRYPTO_SHA256
|
||||
|
||||
#ifdef HITLS_CRYPTO_SHA384
|
||||
|
||||
@@ -471,4 +471,385 @@ SHA256CryptoExt:
|
||||
st1 {v4.4s-v5.4s}, [x0]
|
||||
ret
|
||||
.size SHA256CryptoExt, .-SHA256CryptoExt
|
||||
|
||||
/*
|
||||
* Optimized macro for dual SHA-256 rounds - caller-saved registers only
|
||||
* Uses on-demand K256 loading to comply with AAPCS calling convention
|
||||
* v8-v15 are callee-saved and must be preserved
|
||||
*/
|
||||
.macro ROUNDS4X2_LOAD m0_a, m0_b, k
|
||||
mov v30.16b, v4.16b
|
||||
mov v31.16b, v6.16b
|
||||
add v28.4s, v\k\().4s, v\m0_a\().4s
|
||||
add v29.4s, v\k\().4s, v\m0_b\().4s
|
||||
sha256h q4, q5, v28.4s
|
||||
sha256h q6, q7, v29.4s
|
||||
sha256h2 q5, q30, v28.4s
|
||||
sha256h2 q7, q31, v29.4s
|
||||
.endm
|
||||
|
||||
/* Macro for round with message schedule update */
|
||||
.macro ROUND_SCHED m0, m1, m2, m3, m0b, m1b, m2b, m3b, k
|
||||
ROUNDS4X2_LOAD \m0, \m0b, \k
|
||||
sha256su0 v\m0\().4s, v\m1\().4s
|
||||
sha256su0 v\m0b\().4s, v\m1b\().4s
|
||||
sha256su1 v\m0\().4s, v\m2\().4s, v\m3\().4s
|
||||
sha256su1 v\m0b\().4s, v\m2b\().4s, v\m3b\().4s
|
||||
.endm
|
||||
|
||||
.macro REVBE x0, x1
|
||||
#ifndef HITLS_BIG_ENDIAN
|
||||
rev \x0, \x1
|
||||
#else
|
||||
mov \x0, \x1
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Function: CRYPT_SHA256x2 - Dual SHA-256 hash computation
|
||||
* Prototype: void CRYPT_SHA256x2(uint32_t state1[8], uint32_t state2[8],
|
||||
* const uint8_t *in1, const uint8_t *in2, uint32_t nbytes,
|
||||
* uint8_t dgst1[32], uint8_t dgst2[32]);
|
||||
*
|
||||
* Parameters:
|
||||
* x0 - state1: Initial/final hash state for message 1
|
||||
* x1 - state2: Initial/final hash state for message 2
|
||||
* x2 - in1: Message 1 data pointer
|
||||
* x3 - in2: Message 2 data pointer
|
||||
* w4 - nbytes: Message length (same for both)
|
||||
* x5 - dgst1: Output digest for message 1 (32 bytes, big-endian)
|
||||
* x6 - dgst2: Output digest for message 2 (32 bytes, big-endian)
|
||||
*
|
||||
* Computes two SHA-256 hashes simultaneously using ARMv8 crypto extensions.
|
||||
* Handles padding internally per FIPS 180-4.
|
||||
*/
|
||||
|
||||
.balign 16
|
||||
#ifdef __APPLE__
|
||||
.global _CRYPT_SHA256x2
|
||||
_CRYPT_SHA256x2:
|
||||
#else
|
||||
.global CRYPT_SHA256x2
|
||||
.type CRYPT_SHA256x2, %function
|
||||
CRYPT_SHA256x2:
|
||||
#endif
|
||||
AARCH64_PACIASP
|
||||
/* Stack: 256 bytes
|
||||
* 0-15: x29/x30, 96-159: buffer1, 160-223: buffer2 */
|
||||
stp x29, x30, [sp, #-160]!
|
||||
add x29, sp, #0
|
||||
stp x19, x20, [sp, #16]
|
||||
|
||||
/* Initialize */
|
||||
lsl x19, x4, #3 // bit count for padding
|
||||
ld1 {v24.4s-v25.4s}, [x0] // Load initial state1
|
||||
ld1 {v26.4s-v27.4s}, [x1] // Load initial state2
|
||||
|
||||
/* Process complete 64-byte blocks */
|
||||
lsr w9, w4, #6 // num_blocks = nbytes / 64
|
||||
cbz w9, .L_partial_2x
|
||||
|
||||
.L_fullblk_2x:
|
||||
/* Load 64 bytes from each message and convert to big-endian */
|
||||
ld1 {v16.16b-v19.16b}, [x2], #64
|
||||
ld1 {v20.16b-v23.16b}, [x3], #64
|
||||
rev32 v16.16b, v16.16b
|
||||
rev32 v20.16b, v20.16b
|
||||
rev32 v17.16b, v17.16b
|
||||
rev32 v21.16b, v21.16b
|
||||
rev32 v18.16b, v18.16b
|
||||
rev32 v22.16b, v22.16b
|
||||
rev32 v19.16b, v19.16b
|
||||
rev32 v23.16b, v23.16b
|
||||
|
||||
/* Execute 64 rounds of compression */
|
||||
bl sha256_block_x2
|
||||
|
||||
subs w9, w9, #1
|
||||
bne .L_fullblk_2x
|
||||
|
||||
.L_partial_2x:
|
||||
/* Handle partial block and padding (FIPS 180-4):
|
||||
* Append 0x80, pad with zeros to 56 bytes, append 64-bit length */
|
||||
and w10, w4, #63 // remaining bytes
|
||||
cbz w10, .L_padding_aligned_2x
|
||||
|
||||
/* Clear buffers and copy remaining bytes */
|
||||
add x11, sp, #32
|
||||
movi v28.16b, #0
|
||||
movi v29.16b, #0
|
||||
movi v30.16b, #0
|
||||
movi v31.16b, #0
|
||||
st1 {v28.16b-v31.16b}, [x11], #64
|
||||
st1 {v28.16b-v31.16b}, [x11]
|
||||
|
||||
add x11, sp, #32
|
||||
add x12, sp, #96
|
||||
mov x13, x10
|
||||
|
||||
/* Copy 16-byte chunks */
|
||||
cmp x13, #16
|
||||
blt .L_copy_bytes_2x
|
||||
.L_copy_16_2x:
|
||||
ldr q28, [x2], #16
|
||||
ldr q29, [x3], #16
|
||||
str q28, [x11], #16
|
||||
str q29, [x12], #16
|
||||
sub x13, x13, #16
|
||||
cmp x13, #16
|
||||
bge .L_copy_16_2x
|
||||
|
||||
/* Copy remaining bytes */
|
||||
.L_copy_bytes_2x:
|
||||
cbz x13, .L_add_padding_2x
|
||||
ldrb w14, [x2], #1
|
||||
ldrb w15, [x3], #1
|
||||
strb w14, [x11], #1
|
||||
strb w15, [x12], #1
|
||||
subs x13, x13, #1
|
||||
bne .L_copy_bytes_2x
|
||||
|
||||
.L_add_padding_2x:
|
||||
/* Add 0x80 padding byte */
|
||||
mov w13, #0x80
|
||||
add x14, sp, #32
|
||||
add x15, sp, #96
|
||||
strb w13, [x14, x10]
|
||||
strb w13, [x15, x10]
|
||||
|
||||
/* Check if need one or two blocks */
|
||||
cmp w10, #56
|
||||
bge .L_need_extra_block_2x
|
||||
|
||||
/* Case 1: Padding fits in one block */
|
||||
REVBE x8, x19
|
||||
add x14, sp, #32
|
||||
add x15, sp, #96
|
||||
str x8, [x14, #56]
|
||||
str x8, [x15, #56]
|
||||
|
||||
ld1 {v16.16b-v19.16b}, [x14]
|
||||
ld1 {v20.16b-v23.16b}, [x15]
|
||||
rev32 v16.16b, v16.16b
|
||||
rev32 v20.16b, v20.16b
|
||||
rev32 v17.16b, v17.16b
|
||||
rev32 v21.16b, v21.16b
|
||||
rev32 v18.16b, v18.16b
|
||||
rev32 v22.16b, v22.16b
|
||||
rev32 v19.16b, v19.16b
|
||||
rev32 v23.16b, v23.16b
|
||||
b .L_process_final_2x
|
||||
|
||||
.L_need_extra_block_2x:
|
||||
/* Case 2: Need two blocks (remaining >= 56) */
|
||||
add x14, sp, #32
|
||||
add x15, sp, #96
|
||||
ld1 {v16.16b-v19.16b}, [x14]
|
||||
ld1 {v20.16b-v23.16b}, [x15]
|
||||
rev32 v16.16b, v16.16b
|
||||
rev32 v20.16b, v20.16b
|
||||
rev32 v17.16b, v17.16b
|
||||
rev32 v21.16b, v21.16b
|
||||
rev32 v18.16b, v18.16b
|
||||
rev32 v22.16b, v22.16b
|
||||
rev32 v19.16b, v19.16b
|
||||
rev32 v23.16b, v23.16b
|
||||
bl sha256_block_x2
|
||||
|
||||
/* Prepare second block: zeros + length */
|
||||
/* For direct vector register manipulation, always use rev (not REVBE)
|
||||
* because mov v.d[n], x is a pure bit copy, independent of system endianness */
|
||||
rev x8, x19
|
||||
movi v16.2d, #0
|
||||
movi v17.2d, #0
|
||||
movi v18.2d, #0
|
||||
mov v19.d[0], xzr
|
||||
mov v19.d[1], x8
|
||||
mov v20.16b, v16.16b
|
||||
mov v21.16b, v17.16b
|
||||
mov v22.16b, v18.16b
|
||||
mov v23.16b, v19.16b
|
||||
rev32 v16.16b, v16.16b
|
||||
rev32 v17.16b, v17.16b
|
||||
rev32 v18.16b, v18.16b
|
||||
rev32 v19.16b, v19.16b
|
||||
rev32 v20.16b, v20.16b
|
||||
rev32 v21.16b, v21.16b
|
||||
rev32 v22.16b, v22.16b
|
||||
rev32 v23.16b, v23.16b
|
||||
b .L_process_final_2x
|
||||
|
||||
.L_padding_aligned_2x:
|
||||
/* Case 3: Block-aligned message */
|
||||
add x14, sp, #32
|
||||
add x15, sp, #96
|
||||
movi v28.16b, #0
|
||||
movi v29.16b, #0
|
||||
movi v30.16b, #0
|
||||
movi v31.16b, #0
|
||||
st1 {v28.16b-v31.16b}, [x14]
|
||||
st1 {v28.16b-v31.16b}, [x15]
|
||||
|
||||
mov w13, #0x80
|
||||
add x14, sp, #32
|
||||
add x15, sp, #96
|
||||
strb w13, [x14]
|
||||
strb w13, [x15]
|
||||
REVBE x8, x19
|
||||
str x8, [x14, #56]
|
||||
str x8, [x15, #56]
|
||||
|
||||
ld1 {v16.16b-v19.16b}, [x14]
|
||||
ld1 {v20.16b-v23.16b}, [x15]
|
||||
rev32 v16.16b, v16.16b
|
||||
rev32 v20.16b, v20.16b
|
||||
rev32 v17.16b, v17.16b
|
||||
rev32 v21.16b, v21.16b
|
||||
rev32 v18.16b, v18.16b
|
||||
rev32 v22.16b, v22.16b
|
||||
rev32 v19.16b, v19.16b
|
||||
rev32 v23.16b, v23.16b
|
||||
|
||||
.L_process_final_2x:
|
||||
bl sha256_block_x2
|
||||
|
||||
.L_finalize_2x:
|
||||
/* Output results: state arrays (little-endian) and digests (big-endian) */
|
||||
st1 {v24.4s-v25.4s}, [x0]
|
||||
st1 {v26.4s-v27.4s}, [x1]
|
||||
#ifndef HITLS_BIG_ENDIAN
|
||||
rev32 v24.16b, v24.16b
|
||||
rev32 v25.16b, v25.16b
|
||||
rev32 v26.16b, v26.16b
|
||||
rev32 v27.16b, v27.16b
|
||||
#endif
|
||||
st1 {v24.4s-v25.4s}, [x5]
|
||||
st1 {v26.4s-v27.4s}, [x6]
|
||||
|
||||
ldp x19, x20, [sp, #16]
|
||||
ldp x29, x30, [sp], #160
|
||||
AARCH64_AUTIASP
|
||||
ret
|
||||
#ifndef __APPLE__
|
||||
.size CRYPT_SHA256x2, .-CRYPT_SHA256x2
|
||||
#endif
|
||||
|
||||
/* Local subroutine: 64-round SHA-256 compression for dual messages
|
||||
* Input: v16-v19, v20-v23 (msg schedules), v24-v27 (states)
|
||||
* Modifies: v0-v7, v16-v23, v28-v31, x16 */
|
||||
sha256_block_x2:
|
||||
mov v4.16b, v24.16b
|
||||
mov v5.16b, v25.16b
|
||||
mov v6.16b, v26.16b
|
||||
mov v7.16b, v27.16b
|
||||
|
||||
#ifdef __APPLE__
|
||||
adrp x16, .K256@page
|
||||
add x16, x16, .K256@pageoff
|
||||
#else
|
||||
adrp x16, .K256
|
||||
add x16, x16, :lo12:.K256
|
||||
#endif
|
||||
|
||||
/* Rounds 0-47 */
|
||||
ld1 {v0.4s-v3.4s}, [x16], #64
|
||||
ROUND_SCHED 16, 17, 18, 19, 20, 21, 22, 23, 0
|
||||
ROUND_SCHED 17, 18, 19, 16, 21, 22, 23, 20, 1
|
||||
ROUND_SCHED 18, 19, 16, 17, 22, 23, 20, 21, 2
|
||||
ROUND_SCHED 19, 16, 17, 18, 23, 20, 21, 22, 3
|
||||
ld1 {v0.4s-v3.4s}, [x16], #64
|
||||
ROUND_SCHED 16, 17, 18, 19, 20, 21, 22, 23, 0
|
||||
ROUND_SCHED 17, 18, 19, 16, 21, 22, 23, 20, 1
|
||||
ROUND_SCHED 18, 19, 16, 17, 22, 23, 20, 21, 2
|
||||
ROUND_SCHED 19, 16, 17, 18, 23, 20, 21, 22, 3
|
||||
ld1 {v0.4s-v3.4s}, [x16], #64
|
||||
ROUND_SCHED 16, 17, 18, 19, 20, 21, 22, 23, 0
|
||||
ROUND_SCHED 17, 18, 19, 16, 21, 22, 23, 20, 1
|
||||
ROUND_SCHED 18, 19, 16, 17, 22, 23, 20, 21, 2
|
||||
ROUND_SCHED 19, 16, 17, 18, 23, 20, 21, 22, 3
|
||||
|
||||
/* Rounds 48-63 */
|
||||
ld1 {v0.4s-v3.4s}, [x16], #64
|
||||
ROUNDS4X2_LOAD 16, 20, 0
|
||||
ROUNDS4X2_LOAD 17, 21, 1
|
||||
ROUNDS4X2_LOAD 18, 22, 2
|
||||
ROUNDS4X2_LOAD 19, 23, 3
|
||||
|
||||
/* Add to state */
|
||||
add v24.4s, v24.4s, v4.4s
|
||||
add v25.4s, v25.4s, v5.4s
|
||||
add v26.4s, v26.4s, v6.4s
|
||||
add v27.4s, v27.4s, v7.4s
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* void CRYPT_SHA256x2_Compress(uint32_t state1[CRYPT_SHA256_STATE_SIZE], uint32_t state2[CRYPT_SHA256_STATE_SIZE],
|
||||
* const uint8_t *block1, const uint8_t *block2, uint32_t nblocks);
|
||||
*
|
||||
* Function: Compress multiple blocks for dual SHA-256 computation
|
||||
* Parameters:
|
||||
* x0 - state1: Initial/final hash state for message 1
|
||||
* x1 - state2: Initial/final hash state for message 2
|
||||
* x2 - block1: Message 1 data pointer
|
||||
* x3 - block2: Message 2 data pointer
|
||||
* w4 - nblocks: Number of 64-byte blocks to process
|
||||
*
|
||||
* Updates two SHA-256 states by compressing nblocks pairs of 64-byte blocks.
|
||||
*/
|
||||
|
||||
.balign 16
|
||||
#ifdef __APPLE__
|
||||
.global _CRYPT_SHA256x2_Compress
|
||||
_CRYPT_SHA256x2_Compress:
|
||||
#else
|
||||
.global CRYPT_SHA256x2_Compress
|
||||
.type CRYPT_SHA256x2_Compress, %function
|
||||
CRYPT_SHA256x2_Compress:
|
||||
#endif
|
||||
AARCH64_PACIASP
|
||||
stp x29, x30, [sp, #-16]!
|
||||
add x29, sp, #0
|
||||
/* Check if nblocks is zero */
|
||||
cbz w4, .Lcompress_end_x2
|
||||
|
||||
/* Load initial states */
|
||||
ld1 {v24.4s-v25.4s}, [x0] // Load state1 (8 uint32_t = 2 vectors)
|
||||
ld1 {v26.4s-v27.4s}, [x1] // Load state2 (8 uint32_t = 2 vectors)
|
||||
|
||||
/* Loop through nblocks */
|
||||
.Lcompress_loop_x2:
|
||||
/* Load 64 bytes from each block */
|
||||
ld1 {v16.16b-v19.16b}, [x2], #64 // Load block1 (64 bytes = 4 vectors)
|
||||
ld1 {v20.16b-v23.16b}, [x3], #64 // Load block2 (64 bytes = 4 vectors)
|
||||
|
||||
/* Convert to big-endian (SHA-256 requires big-endian input) */
|
||||
rev32 v16.16b, v16.16b
|
||||
rev32 v17.16b, v17.16b
|
||||
rev32 v18.16b, v18.16b
|
||||
rev32 v19.16b, v19.16b
|
||||
rev32 v20.16b, v20.16b
|
||||
rev32 v21.16b, v21.16b
|
||||
rev32 v22.16b, v22.16b
|
||||
rev32 v23.16b, v23.16b
|
||||
|
||||
/* Execute 64 rounds of compression */
|
||||
bl sha256_block_x2
|
||||
|
||||
/* Decrement block counter and loop if more blocks remain */
|
||||
subs w4, w4, #1
|
||||
bne .Lcompress_loop_x2
|
||||
|
||||
/* Store final states */
|
||||
st1 {v24.4s-v25.4s}, [x0] // Store state1
|
||||
st1 {v26.4s-v27.4s}, [x1] // Store state2
|
||||
|
||||
.Lcompress_end_x2:
|
||||
ldp x29, x30, [sp], #16
|
||||
AARCH64_AUTIASP
|
||||
ret
|
||||
#ifndef __APPLE__
|
||||
.size CRYPT_SHA256x2_Compress, .-CRYPT_SHA256x2_Compress
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+230
-20
@@ -25,6 +25,10 @@
|
||||
#include "bsl_sal.h"
|
||||
#include "crypt_types.h"
|
||||
|
||||
#define SHA256_INIT_ARRAY {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}
|
||||
|
||||
static const uint32_t SHA256_INIT_STATE[8] = SHA256_INIT_ARRAY;
|
||||
|
||||
struct CryptSha256Ctx {
|
||||
uint32_t h[CRYPT_SHA2_256_DIGESTSIZE / sizeof(uint32_t)]; /* 256 bits for SHA256 state */
|
||||
uint32_t block[CRYPT_SHA2_256_BLOCKSIZE / sizeof(uint32_t)]; /* 512 bits block cache */
|
||||
@@ -68,14 +72,7 @@ int32_t CRYPT_SHA2_256_Init(CRYPT_SHA2_256_Ctx *ctx, BSL_Param *param)
|
||||
* H(0)6 = 1f83d9ab
|
||||
* H(0)7 = 5be0cd19
|
||||
*/
|
||||
ctx->h[0] = 0x6a09e667UL;
|
||||
ctx->h[1] = 0xbb67ae85UL;
|
||||
ctx->h[2] = 0x3c6ef372UL;
|
||||
ctx->h[3] = 0xa54ff53aUL;
|
||||
ctx->h[4] = 0x510e527fUL;
|
||||
ctx->h[5] = 0x9b05688cUL;
|
||||
ctx->h[6] = 0x1f83d9abUL;
|
||||
ctx->h[7] = 0x5be0cd19UL;
|
||||
(void)memcpy_s(ctx->h, sizeof(SHA256_INIT_STATE), SHA256_INIT_STATE, sizeof(SHA256_INIT_STATE));
|
||||
ctx->outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
@@ -173,18 +170,12 @@ int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint
|
||||
uint8_t *p = (uint8_t *)ctx->block;
|
||||
|
||||
if (left < CRYPT_SHA2_256_BLOCKSIZE - n) {
|
||||
if (memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, left) != EOK) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
|
||||
return CRYPT_SECUREC_FAIL;
|
||||
}
|
||||
(void)memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, left);
|
||||
ctx->blocklen += (uint32_t)left;
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
if ((n != 0) && (left >= CRYPT_SHA2_256_BLOCKSIZE - n)) {
|
||||
if (memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, CRYPT_SHA2_256_BLOCKSIZE - n) != EOK) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
|
||||
return CRYPT_SECUREC_FAIL;
|
||||
}
|
||||
(void)memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, CRYPT_SHA2_256_BLOCKSIZE - n);
|
||||
SHA256CompressMultiBlocks(ctx->h, p, 1);
|
||||
n = CRYPT_SHA2_256_BLOCKSIZE - n;
|
||||
d += n;
|
||||
@@ -203,10 +194,7 @@ int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint
|
||||
|
||||
if (left != 0) {
|
||||
ctx->blocklen = (uint32_t)left;
|
||||
if (memcpy_s((uint8_t *)ctx->block, CRYPT_SHA2_256_BLOCKSIZE, d, left) != EOK) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
|
||||
return CRYPT_SECUREC_FAIL;
|
||||
}
|
||||
(void)memcpy_s((uint8_t *)ctx->block, CRYPT_SHA2_256_BLOCKSIZE, d, left);
|
||||
}
|
||||
|
||||
return CRYPT_SUCCESS;
|
||||
@@ -269,6 +257,228 @@ int32_t CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx *ctx, uint8_t *digest, uint32_t
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HITLS_CRYPTO_SHA2_MB
|
||||
|
||||
CRYPT_SHA2_256_MB_Ctx *CRYPT_SHA256_MBNewCtx(uint32_t num)
|
||||
{
|
||||
if (num != 2) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NOT_SUPPORT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CRYPT_SHA2_256_MB_Ctx *mbCtx = BSL_SAL_Calloc(1, sizeof(CRYPT_SHA2_256_MB_Ctx));
|
||||
if (mbCtx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbCtx->ctxs = BSL_SAL_Calloc(num, sizeof(CRYPT_SHA2_256_Ctx));
|
||||
if (mbCtx->ctxs == NULL) {
|
||||
BSL_SAL_Free(mbCtx);
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbCtx->num = num;
|
||||
return mbCtx;
|
||||
}
|
||||
|
||||
void CRYPT_SHA256_MBFreeCtx(CRYPT_SHA2_256_MB_Ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->ctxs != NULL) {
|
||||
for (uint32_t i = 0; i < ctx->num; i++) {
|
||||
(void)CRYPT_SHA2_256_Deinit(&ctx->ctxs[i]);
|
||||
}
|
||||
BSL_SAL_Free(ctx->ctxs);
|
||||
}
|
||||
BSL_SAL_Free(ctx);
|
||||
}
|
||||
|
||||
int32_t CRYPT_SHA256_MBInit(CRYPT_SHA2_256_MB_Ctx *ctx)
|
||||
{
|
||||
#if defined(__aarch64__)
|
||||
// currently only support sha256x2 in aarch64
|
||||
if (UNLIKELY(ctx == NULL)) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
if (UNLIKELY(ctx->num != 2)) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NOT_SUPPORT);
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
}
|
||||
(void)CRYPT_SHA2_256_Init(&ctx->ctxs[0], NULL);
|
||||
(void)CRYPT_SHA2_256_Init(&ctx->ctxs[1], NULL);
|
||||
return CRYPT_SUCCESS;
|
||||
#else
|
||||
(void)ctx;
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t CRYPT_SHA256_MBUpdate(CRYPT_SHA2_256_MB_Ctx *ctx, const uint8_t *data[], uint32_t nbytes[], uint32_t num)
|
||||
{
|
||||
#if defined(__aarch64__) && defined(HITLS_CRYPTO_SHA2_ASM)
|
||||
// currently only support sha256x2 in aarch64
|
||||
if (UNLIKELY(ctx == NULL || data == NULL || nbytes == NULL)) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
if (UNLIKELY(num != 2 || ctx->num != num || nbytes[0] != nbytes[1])) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NOT_SUPPORT);
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
}
|
||||
uint32_t commonBytes = nbytes[0];
|
||||
if (commonBytes == 0) {
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
CRYPT_SHA2_256_Ctx *ctx0 = &ctx->ctxs[0];
|
||||
CRYPT_SHA2_256_Ctx *ctx1 = &ctx->ctxs[1];
|
||||
|
||||
int32_t ret = UpdateParamIsValid(ctx0, data[0], commonBytes);
|
||||
if (ret != CRYPT_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = UpdateParamIsValid(ctx1, data[1], commonBytes);
|
||||
if (ret != CRYPT_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t *b0 = (uint8_t *)(uintptr_t)ctx0->block;
|
||||
uint8_t *b1 = (uint8_t *)(uintptr_t)ctx1->block;
|
||||
const uint8_t *d0 = data[0];
|
||||
const uint8_t *d1 = data[1];
|
||||
uint32_t caches = ctx0->blocklen;
|
||||
if (caches + commonBytes >= CRYPT_SHA2_256_BLOCKSIZE) {
|
||||
if (caches != 0) {
|
||||
uint32_t cpysize = CRYPT_SHA2_256_BLOCKSIZE - caches;
|
||||
(void)memcpy_s(b0 + caches, cpysize, d0, cpysize);
|
||||
d0 += cpysize;
|
||||
(void)memcpy_s(b1 + caches, cpysize, d1, cpysize);
|
||||
d1 += cpysize;
|
||||
commonBytes -= cpysize;
|
||||
CRYPT_SHA256x2_Compress(ctx0->h, ctx1->h, b0, b1, 1);
|
||||
ctx0->blocklen = 0;
|
||||
ctx1->blocklen = 0;
|
||||
}
|
||||
uint32_t nblocks = commonBytes / CRYPT_SHA2_256_BLOCKSIZE;
|
||||
commonBytes &= (CRYPT_SHA2_256_BLOCKSIZE - 1);
|
||||
if (nblocks > 0) {
|
||||
CRYPT_SHA256x2_Compress(ctx0->h, ctx1->h, d0, d1, nblocks);
|
||||
d0 += nblocks * CRYPT_SHA2_256_BLOCKSIZE;
|
||||
d1 += nblocks * CRYPT_SHA2_256_BLOCKSIZE;
|
||||
}
|
||||
caches = 0;
|
||||
}
|
||||
if (commonBytes != 0) {
|
||||
(void)memcpy_s(b0 + caches, CRYPT_SHA2_256_BLOCKSIZE - caches, d0, commonBytes);
|
||||
(void)memcpy_s(b1 + caches, CRYPT_SHA2_256_BLOCKSIZE - caches, d1, commonBytes);
|
||||
ctx0->blocklen += commonBytes;
|
||||
ctx1->blocklen += commonBytes;
|
||||
}
|
||||
return CRYPT_SUCCESS;
|
||||
#else
|
||||
(void)ctx;
|
||||
(void)data;
|
||||
(void)nbytes;
|
||||
(void)num;
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t CRYPT_SHA256_MBFinal(CRYPT_SHA2_256_MB_Ctx *ctx, uint8_t *digest[], uint32_t *outlen, uint32_t num)
|
||||
{
|
||||
#if defined(__aarch64__) && defined(HITLS_CRYPTO_SHA2_ASM)
|
||||
// currently only support sha256x2 in aarch64
|
||||
if (UNLIKELY(ctx == NULL || digest == NULL || outlen == NULL)) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
if (UNLIKELY(num != 2 || ctx->num != num)) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NOT_SUPPORT);
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (UNLIKELY(digest[0] == NULL || digest[1] == NULL)) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
|
||||
CRYPT_SHA2_256_Ctx *ctx0 = &ctx->ctxs[0];
|
||||
CRYPT_SHA2_256_Ctx *ctx1 = &ctx->ctxs[1];
|
||||
int32_t ret = FinalParamIsValid(ctx0, digest[0], outlen);
|
||||
if (ret != CRYPT_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = FinalParamIsValid(ctx1, digest[1], outlen);
|
||||
if (ret != CRYPT_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
uint8_t *b0 = (uint8_t *)(uintptr_t)ctx0->block;
|
||||
uint8_t *b1 = (uint8_t *)(uintptr_t)ctx1->block;
|
||||
uint32_t caches = ctx0->blocklen;
|
||||
b0[caches] = 0x80;
|
||||
b1[caches++] = 0x80;
|
||||
if (caches > (CRYPT_SHA2_256_BLOCKSIZE - 8)) {
|
||||
(void)memset_s(b0 + caches, CRYPT_SHA2_256_BLOCKSIZE - caches, 0, CRYPT_SHA2_256_BLOCKSIZE - caches);
|
||||
(void)memset_s(b1 + caches, CRYPT_SHA2_256_BLOCKSIZE - caches, 0, CRYPT_SHA2_256_BLOCKSIZE - caches);
|
||||
caches = 0;
|
||||
CRYPT_SHA256x2_Compress(ctx0->h, ctx1->h, b0, b1, 1);
|
||||
}
|
||||
(void)memset_s(b0 + caches, CRYPT_SHA2_256_BLOCKSIZE - caches, 0,
|
||||
CRYPT_SHA2_256_BLOCKSIZE - 8 - caches); /* 8 bytes to save bits of input */
|
||||
(void)memset_s(b1 + caches, CRYPT_SHA2_256_BLOCKSIZE - caches, 0,
|
||||
CRYPT_SHA2_256_BLOCKSIZE - 8 - caches); /* 8 bytes to save bits of input */
|
||||
PUT_UINT32_BE(ctx0->hNum, b0, CRYPT_SHA2_256_BLOCKSIZE - 8);
|
||||
PUT_UINT32_BE(ctx0->lNum, b0, CRYPT_SHA2_256_BLOCKSIZE - 4);
|
||||
PUT_UINT32_BE(ctx1->hNum, b1, CRYPT_SHA2_256_BLOCKSIZE - 8);
|
||||
PUT_UINT32_BE(ctx1->lNum, b1, CRYPT_SHA2_256_BLOCKSIZE - 4);
|
||||
CRYPT_SHA256x2_Compress(ctx0->h, ctx1->h, b0, b1, 1);
|
||||
ctx0->blocklen = 0;
|
||||
ctx1->blocklen = 0;
|
||||
for (uint32_t i = 0; i < ctx0->outlen / sizeof(uint32_t); i++) {
|
||||
PUT_UINT32_BE(ctx0->h[i], digest[0], sizeof(uint32_t) * i);
|
||||
PUT_UINT32_BE(ctx1->h[i], digest[1], sizeof(uint32_t) * i);
|
||||
}
|
||||
*outlen = ctx0->outlen;
|
||||
return CRYPT_SUCCESS;
|
||||
#else
|
||||
(void)ctx;
|
||||
(void)digest;
|
||||
(void)outlen;
|
||||
(void)num;
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t CRYPT_SHA256_MB(const uint8_t *data[], uint32_t nbytes, uint8_t *digest[], uint32_t *outlen, uint32_t num)
|
||||
{
|
||||
#if defined(__aarch64__) && defined(HITLS_CRYPTO_SHA2_ASM)
|
||||
// currently only support sha256x2 in aarch64
|
||||
if (num != 2) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NOT_SUPPORT);
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
}
|
||||
uint32_t state1[CRYPT_SHA256_STATE_SIZE] = SHA256_INIT_ARRAY;
|
||||
uint32_t state2[CRYPT_SHA256_STATE_SIZE] = SHA256_INIT_ARRAY;
|
||||
(void)CRYPT_SHA256x2(state1, state2, data[0], data[1], nbytes, digest[0], digest[1]);
|
||||
*outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
return CRYPT_SUCCESS;
|
||||
#else
|
||||
(void)data;
|
||||
(void)nbytes;
|
||||
(void)digest;
|
||||
(void)outlen;
|
||||
(void)num;
|
||||
return CRYPT_NOT_SUPPORT;
|
||||
#endif
|
||||
}
|
||||
#endif // HITLS_CRYPTO_SHA2_MB
|
||||
|
||||
#ifdef HITLS_CRYPTO_SHA224
|
||||
|
||||
|
||||
|
||||
@@ -32,15 +32,6 @@ static void Round(const uint64_t *a, uint64_t *e, uint32_t i);
|
||||
|
||||
#define ROL64(a, offset) ((((uint64_t)(a)) << (offset)) ^ (((uint64_t)(a)) >> (64 - (offset))))
|
||||
|
||||
// the rotation offsets, see https://keccak.team/keccak_specs_summary.html
|
||||
static const uint8_t g_rotationOffset[5][5] = {
|
||||
{ 0, 1, 62, 28, 27 },
|
||||
{ 36, 44, 6, 55, 20 },
|
||||
{ 3, 10, 43, 25, 39 },
|
||||
{ 41, 45, 15, 21, 8 },
|
||||
{ 18, 2, 61, 56, 14 }
|
||||
};
|
||||
|
||||
// the round constants, see https://keccak.team/keccak_specs_summary.html
|
||||
static const uint64_t g_roundConstant[24] = {
|
||||
(uint64_t)0x0000000000000001, (uint64_t)0x0000000000008082,
|
||||
@@ -120,95 +111,102 @@ static void SHA3_Keccak(uint8_t *state)
|
||||
// see section 2.4 Algorithm 1 in https://keccak.team/files/Keccak-implementation-3.2.pdf
|
||||
static void Round(const uint64_t *a, uint64_t *e, uint32_t i)
|
||||
{
|
||||
uint64_t c[5], d[5];
|
||||
// Use separate variables instead of arrays for better register allocation on x86
|
||||
uint64_t c0, c1, c2, c3, c4;
|
||||
uint64_t d0, d1, d2, d3, d4;
|
||||
|
||||
// The corresponding formula for calculating the indexes of array A and array E is (5 * x) + y,
|
||||
// the value of x is in [0, 4] and the value of y is [0, 4].
|
||||
// The row coordinates of the array index correspond to y in the algorithm principle,
|
||||
// and the column coordinates correspond to x in the algorithm principle, for example, A[1, 1] = A[5 * 1 + 1] = A[6]
|
||||
// THETA operation
|
||||
c[0] = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20];
|
||||
c[1] = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21];
|
||||
c[2] = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22];
|
||||
c[3] = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23];
|
||||
c[4] = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24];
|
||||
c0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20];
|
||||
c1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21];
|
||||
c2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22];
|
||||
c3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23];
|
||||
c4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24];
|
||||
|
||||
d[0] = ROL64(c[1], 1) ^ c[4];
|
||||
d[1] = ROL64(c[2], 1) ^ c[0];
|
||||
d[2] = ROL64(c[3], 1) ^ c[1];
|
||||
d[3] = ROL64(c[4], 1) ^ c[2];
|
||||
d[4] = ROL64(c[0], 1) ^ c[3];
|
||||
d0 = ROL64(c1, 1) ^ c4;
|
||||
d1 = ROL64(c2, 1) ^ c0;
|
||||
d2 = ROL64(c3, 1) ^ c1;
|
||||
d3 = ROL64(c4, 1) ^ c2;
|
||||
d4 = ROL64(c0, 1) ^ c3;
|
||||
|
||||
// THETA RHP Pi operation
|
||||
c[0] = a[0] ^ d[0];
|
||||
c[1] = ROL64(a[6] ^ d[1], g_rotationOffset[1][1]);
|
||||
c[2] = ROL64(a[12] ^ d[2], g_rotationOffset[2][2]);
|
||||
c[3] = ROL64(a[18] ^ d[3], g_rotationOffset[3][3]);
|
||||
c[4] = ROL64(a[24] ^ d[4], g_rotationOffset[4][4]);
|
||||
// THETA RHP Pi operation - rotation offsets inlined as constants
|
||||
// g_rotationOffset[0][0]=0, [1][1]=44, [2][2]=43, [3][3]=21, [4][4]=14
|
||||
c0 = a[0] ^ d0;
|
||||
c1 = ROL64(a[6] ^ d1, 44);
|
||||
c2 = ROL64(a[12] ^ d2, 43);
|
||||
c3 = ROL64(a[18] ^ d3, 21);
|
||||
c4 = ROL64(a[24] ^ d4, 14);
|
||||
|
||||
// CHI IOTA operation,
|
||||
e[0] = c[0] ^ (~c[1] & c[2]) ^ g_roundConstant[i];
|
||||
e[0] = c0 ^ (~c1 & c2) ^ g_roundConstant[i];
|
||||
// CHI operation
|
||||
e[1] = c[1] ^ (~c[2] & c[3]);
|
||||
e[2] = c[2] ^ (~c[3] & c[4]);
|
||||
e[3] = c[3] ^ (~c[4] & c[0]);
|
||||
e[4] = c[4] ^ (~c[0] & c[1]);
|
||||
e[1] = c1 ^ (~c2 & c3);
|
||||
e[2] = c2 ^ (~c3 & c4);
|
||||
e[3] = c3 ^ (~c4 & c0);
|
||||
e[4] = c4 ^ (~c0 & c1);
|
||||
|
||||
// THETA RHP Pi operation
|
||||
c[0] = ROL64(a[3] ^ d[3], g_rotationOffset[0][3]);
|
||||
c[1] = ROL64(a[9] ^ d[4], g_rotationOffset[1][4]);
|
||||
c[2] = ROL64(a[10] ^ d[0], g_rotationOffset[2][0]);
|
||||
c[3] = ROL64(a[16] ^ d[1], g_rotationOffset[3][1]);
|
||||
c[4] = ROL64(a[22] ^ d[2], g_rotationOffset[4][2]);
|
||||
// g_rotationOffset[0][3]=28, [1][4]=20, [2][0]=3, [3][1]=45, [4][2]=61
|
||||
c0 = ROL64(a[3] ^ d3, 28);
|
||||
c1 = ROL64(a[9] ^ d4, 20);
|
||||
c2 = ROL64(a[10] ^ d0, 3);
|
||||
c3 = ROL64(a[16] ^ d1, 45);
|
||||
c4 = ROL64(a[22] ^ d2, 61);
|
||||
|
||||
// CHI operation
|
||||
e[5] = c[0] ^ (~c[1] & c[2]);
|
||||
e[6] = c[1] ^ (~c[2] & c[3]);
|
||||
e[7] = c[2] ^ (~c[3] & c[4]);
|
||||
e[8] = c[3] ^ (~c[4] & c[0]);
|
||||
e[9] = c[4] ^ (~c[0] & c[1]);
|
||||
e[5] = c0 ^ (~c1 & c2);
|
||||
e[6] = c1 ^ (~c2 & c3);
|
||||
e[7] = c2 ^ (~c3 & c4);
|
||||
e[8] = c3 ^ (~c4 & c0);
|
||||
e[9] = c4 ^ (~c0 & c1);
|
||||
|
||||
// THETA RHP Pi operation
|
||||
c[0] = ROL64(a[1] ^ d[1], g_rotationOffset[0][1]);
|
||||
c[1] = ROL64(a[7] ^ d[2], g_rotationOffset[1][2]);
|
||||
c[2] = ROL64(a[13] ^ d[3], g_rotationOffset[2][3]);
|
||||
c[3] = ROL64(a[19] ^ d[4], g_rotationOffset[3][4]);
|
||||
c[4] = ROL64(a[20] ^ d[0], g_rotationOffset[4][0]);
|
||||
// g_rotationOffset[0][1]=1, [1][2]=6, [2][3]=25, [3][4]=8, [4][0]=18
|
||||
c0 = ROL64(a[1] ^ d1, 1);
|
||||
c1 = ROL64(a[7] ^ d2, 6);
|
||||
c2 = ROL64(a[13] ^ d3, 25);
|
||||
c3 = ROL64(a[19] ^ d4, 8);
|
||||
c4 = ROL64(a[20] ^ d0, 18);
|
||||
|
||||
// CHI operation
|
||||
e[10] = c[0] ^ (~c[1] & c[2]);
|
||||
e[11] = c[1] ^ (~c[2] & c[3]);
|
||||
e[12] = c[2] ^ (~c[3] & c[4]);
|
||||
e[13] = c[3] ^ (~c[4] & c[0]);
|
||||
e[14] = c[4] ^ (~c[0] & c[1]);
|
||||
e[10] = c0 ^ (~c1 & c2);
|
||||
e[11] = c1 ^ (~c2 & c3);
|
||||
e[12] = c2 ^ (~c3 & c4);
|
||||
e[13] = c3 ^ (~c4 & c0);
|
||||
e[14] = c4 ^ (~c0 & c1);
|
||||
|
||||
// THETA RHP Pi operation
|
||||
c[0] = ROL64(a[4] ^ d[4], g_rotationOffset[0][4]);
|
||||
c[1] = ROL64(a[5] ^ d[0], g_rotationOffset[1][0]);
|
||||
c[2] = ROL64(a[11] ^ d[1], g_rotationOffset[2][1]);
|
||||
c[3] = ROL64(a[17] ^ d[2], g_rotationOffset[3][2]);
|
||||
c[4] = ROL64(a[23] ^ d[3], g_rotationOffset[4][3]);
|
||||
// g_rotationOffset[0][4]=27, [1][0]=36, [2][1]=10, [3][2]=15, [4][3]=56
|
||||
c0 = ROL64(a[4] ^ d4, 27);
|
||||
c1 = ROL64(a[5] ^ d0, 36);
|
||||
c2 = ROL64(a[11] ^ d1, 10);
|
||||
c3 = ROL64(a[17] ^ d2, 15);
|
||||
c4 = ROL64(a[23] ^ d3, 56);
|
||||
|
||||
// CHI operation
|
||||
e[15] = c[0] ^ (~c[1] & c[2]);
|
||||
e[16] = c[1] ^ (~c[2] & c[3]);
|
||||
e[17] = c[2] ^ (~c[3] & c[4]);
|
||||
e[18] = c[3] ^ (~c[4] & c[0]);
|
||||
e[19] = c[4] ^ (~c[0] & c[1]);
|
||||
e[15] = c0 ^ (~c1 & c2);
|
||||
e[16] = c1 ^ (~c2 & c3);
|
||||
e[17] = c2 ^ (~c3 & c4);
|
||||
e[18] = c3 ^ (~c4 & c0);
|
||||
e[19] = c4 ^ (~c0 & c1);
|
||||
|
||||
// THETA RHP Pi operation
|
||||
c[0] = ROL64(a[2] ^ d[2], g_rotationOffset[0][2]);
|
||||
c[1] = ROL64(a[8] ^ d[3], g_rotationOffset[1][3]);
|
||||
c[2] = ROL64(a[14] ^ d[4], g_rotationOffset[2][4]);
|
||||
c[3] = ROL64(a[15] ^ d[0], g_rotationOffset[3][0]);
|
||||
c[4] = ROL64(a[21] ^ d[1], g_rotationOffset[4][1]);
|
||||
// g_rotationOffset[0][2]=62, [1][3]=55, [2][4]=39, [3][0]=41, [4][1]=2
|
||||
c0 = ROL64(a[2] ^ d2, 62);
|
||||
c1 = ROL64(a[8] ^ d3, 55);
|
||||
c2 = ROL64(a[14] ^ d4, 39);
|
||||
c3 = ROL64(a[15] ^ d0, 41);
|
||||
c4 = ROL64(a[21] ^ d1, 2);
|
||||
|
||||
// CHI operation
|
||||
e[20] = c[0] ^ (~c[1] & c[2]);
|
||||
e[21] = c[1] ^ (~c[2] & c[3]);
|
||||
e[22] = c[2] ^ (~c[3] & c[4]);
|
||||
e[23] = c[3] ^ (~c[4] & c[0]);
|
||||
e[24] = c[4] ^ (~c[0] & c[1]);
|
||||
e[20] = c0 ^ (~c1 & c2);
|
||||
e[21] = c1 ^ (~c2 & c3);
|
||||
e[22] = c2 ^ (~c3 & c4);
|
||||
e[23] = c3 ^ (~c4 & c0);
|
||||
e[24] = c4 ^ (~c0 & c1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -418,6 +418,8 @@ typedef enum {
|
||||
BSL_CID_DECODE_UNKNOWN = 1000,
|
||||
BSL_CID_NULL = 1001,
|
||||
|
||||
BSL_CID_SHA256_MB = 1500, /* identifies the SHA256 algorithm (multi-buffer variant) */
|
||||
|
||||
BSL_CID_HMAC_SHA3_224 = 2000, /* identifies hmac with SHA3_224 */
|
||||
BSL_CID_HMAC_SHA3_256 = 2001, /* identifies hmac with SHA3_256 */
|
||||
BSL_CID_HMAC_SHA3_384 = 2002, /* identifies hmac with SHA3_384 */
|
||||
|
||||
@@ -79,6 +79,7 @@ typedef enum {
|
||||
CRYPT_MD_SHAKE128 = BSL_CID_SHAKE128,
|
||||
CRYPT_MD_SHAKE256 = BSL_CID_SHAKE256,
|
||||
CRYPT_MD_SM3 = BSL_CID_SM3,
|
||||
CRYPT_MD_SHA256_MB = BSL_CID_SHA256_MB, /* identifies the SHA256 hash algorithm (multi-buffer variant) */
|
||||
CRYPT_MD_MAX = BSL_CID_UNKNOWN
|
||||
} CRYPT_MD_AlgId;
|
||||
|
||||
|
||||
@@ -203,6 +203,85 @@ int32_t CRYPT_EAL_Md(CRYPT_MD_AlgId id, const uint8_t *in, uint32_t inLen, uint8
|
||||
*/
|
||||
int32_t CRYPT_EAL_MdDeinit(CRYPT_EAL_MdCTX *ctx);
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup crypt_eal_md
|
||||
* @brief Create a MD context for multi-buffer hash computation.
|
||||
*
|
||||
* This interface creates a MB context used by the multi-buffer workflow
|
||||
* (Init/Update/Final) to hash multiple messages in parallel.
|
||||
*
|
||||
* Notes:
|
||||
* - The returned ctx must be released by calling CRYPT_EAL_MdMBFreeCtx.
|
||||
* - The multi-buffer capability is algorithm/feature dependent; unsupported cases
|
||||
* will return #CRYPT_NOT_SUPPORT in subsequent MB operations.
|
||||
*
|
||||
* @param libCtx [IN] Library context (reserved, currently unused).
|
||||
* @param id [IN] MD algorithm ID (e.g. #CRYPT_MD_SHA256).
|
||||
* @param num [IN] Number of contexts/messages.
|
||||
* @retval CRYPT_EAL_MdCTX pointer on success.
|
||||
* NULL if memory allocation fails or input is invalid.
|
||||
*/
|
||||
CRYPT_EAL_MdCTX *CRYPT_EAL_MdMBNewCtx(CRYPT_EAL_LibCtx *libCtx, int32_t id, uint32_t num);
|
||||
|
||||
/**
|
||||
* @ingroup crypt_eal_md
|
||||
* @brief Release MB context created by CRYPT_EAL_MdMBNewCtx.
|
||||
*
|
||||
* @param ctx [IN] MB context pointer.
|
||||
*/
|
||||
void CRYPT_EAL_MdMBFreeCtx(CRYPT_EAL_MdCTX *ctx);
|
||||
|
||||
/**
|
||||
* @ingroup crypt_eal_md
|
||||
* @brief Initialize multi-buffer MD context.
|
||||
*
|
||||
* @param ctx [IN/OUT] MB context created by CRYPT_EAL_MdMBNewCtx.
|
||||
* @retval #CRYPT_SUCCESS on success.
|
||||
* #CRYPT_NULL_INPUT if input is invalid.
|
||||
* #CRYPT_NOT_SUPPORT if the algorithm does not support multi-buffer mode.
|
||||
* For other error codes, see crypt_errno.h.
|
||||
*/
|
||||
int32_t CRYPT_EAL_MdMBInit(CRYPT_EAL_MdCTX *ctx);
|
||||
|
||||
/**
|
||||
* @ingroup crypt_eal_md
|
||||
* @brief Update multi-buffer MD context with message fragments.
|
||||
*
|
||||
* Each update processes one fragment per message.
|
||||
* The fragment length is specified by nbytes[i] for message i. All nbytes[i] must be equal,
|
||||
* otherwise this interface returns #CRYPT_NOT_SUPPORT.
|
||||
*
|
||||
* @param ctx [IN/OUT] MB context.
|
||||
* @param data [IN] Data pointer array. data[i] is the fragment for message i.
|
||||
* @param nbytes [IN] Fragment length array in bytes. nbytes[i] is the fragment length for message i.
|
||||
* @param num [IN] Number of contexts/messages.
|
||||
* @retval #CRYPT_SUCCESS on success.
|
||||
* #CRYPT_NULL_INPUT if input is invalid.
|
||||
* #CRYPT_NOT_SUPPORT if the algorithm does not support multi-buffer mode or the nbytes are not equal.
|
||||
* For other error codes, see crypt_errno.h.
|
||||
*/
|
||||
int32_t CRYPT_EAL_MdMBUpdate(CRYPT_EAL_MdCTX *ctx, const uint8_t *data[], uint32_t nbytes[], uint32_t num);
|
||||
|
||||
/**
|
||||
* @ingroup crypt_eal_md
|
||||
* @brief Finalize multi-buffer MD context and output digests.
|
||||
*
|
||||
* digest[i] is the output buffer for message i. The outlen parameter indicates the
|
||||
* buffer size on input and returns the actual digest length on output.
|
||||
*
|
||||
* @param ctx [IN/OUT] MB context.
|
||||
* @param digest [OUT] Digest buffer pointer array.
|
||||
* @param outlen [IN/OUT] Digest buffer length / output digest length.
|
||||
* @param num [IN] Number of contexts/messages.
|
||||
* @retval #CRYPT_SUCCESS on success.
|
||||
* #CRYPT_NULL_INPUT if input is invalid.
|
||||
* #CRYPT_NOT_SUPPORT if the algorithm does not support multi-buffer mode.
|
||||
* For other error codes, see crypt_errno.h.
|
||||
*/
|
||||
int32_t CRYPT_EAL_MdMBFinal(CRYPT_EAL_MdCTX *ctx, uint8_t *digest[], uint32_t *outlen, uint32_t num);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
@@ -15,7 +15,7 @@ cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
PROJECT(openHiTLS_BENCHMARK)
|
||||
|
||||
set(OPENHITLS_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)
|
||||
set(BENCHS sm2_bench.c)
|
||||
file(GLOB BENCHS "*_bench.c")
|
||||
|
||||
add_compile_options(-g)
|
||||
add_executable(openhitls_benchmark benchmark.c ${BENCHS})
|
||||
|
||||
@@ -74,6 +74,71 @@ CRYPT_EAL_PkeyCtx *TestPkeyNewCtx(
|
||||
CRYPT_EAL_LibCtx *libCtx, int32_t id, uint32_t operType, const char *attrName, int isProvider);
|
||||
#endif
|
||||
|
||||
#ifdef __aarch64__
|
||||
#define AARCH64_PUT_CANARY() \
|
||||
double canaryd = 1.1; \
|
||||
register double d8 asm("d8"); \
|
||||
register double d9 asm("d9"); \
|
||||
register double d10 asm("d10"); \
|
||||
register double d11 asm("d11"); \
|
||||
register double d12 asm("d12"); \
|
||||
register double d13 asm("d13"); \
|
||||
register double d14 asm("d14"); \
|
||||
register double d15 asm("d15"); \
|
||||
asm volatile("fmov %d0, %d1 \n\t" : "=w"(d8) : "w"(canaryd) :); \
|
||||
asm volatile("fmov %d0, %d1 \n\t" : "=w"(d9) : "w"(canaryd) :); \
|
||||
asm volatile("fmov %d0, %d1 \n\t" : "=w"(d10) : "w"(canaryd) :); \
|
||||
asm volatile("fmov %d0, %d1 \n\t" : "=w"(d11) : "w"(canaryd) :); \
|
||||
asm volatile("fmov %d0, %d1 \n\t" : "=w"(d12) : "w"(canaryd) :); \
|
||||
asm volatile("fmov %d0, %d1 \n\t" : "=w"(d13) : "w"(canaryd) :); \
|
||||
asm volatile("fmov %d0, %d1 \n\t" : "=w"(d14) : "w"(canaryd) :); \
|
||||
asm volatile("fmov %d0, %d1 \n\t" : "=w"(d15) : "w"(canaryd) :); \
|
||||
long canaryx = 0x12345678; \
|
||||
register int x19 asm("x19"); \
|
||||
register int x20 asm("x20"); \
|
||||
register int x21 asm("x21"); \
|
||||
register int x22 asm("x22"); \
|
||||
register int x23 asm("x23"); \
|
||||
register int x24 asm("x24"); \
|
||||
register int x25 asm("x25"); \
|
||||
register int x26 asm("x26"); \
|
||||
register int x27 asm("x27"); \
|
||||
register int x28 asm("x28"); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x19) : "r"(canaryx) :); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x20) : "r"(canaryx) :); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x21) : "r"(canaryx) :); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x22) : "r"(canaryx) :); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x23) : "r"(canaryx) :); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x24) : "r"(canaryx) :); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x25) : "r"(canaryx) :); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x26) : "r"(canaryx) :); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x27) : "r"(canaryx) :); \
|
||||
asm volatile("mov %x0, %x1 \n\t" : "=r"(x28) : "r"(canaryx) :);
|
||||
|
||||
#define AARCH64_CHECK_CANARY() \
|
||||
ASSERT_TRUE(d8 == canaryd); \
|
||||
ASSERT_TRUE(d9 == canaryd); \
|
||||
ASSERT_TRUE(d10 == canaryd); \
|
||||
ASSERT_TRUE(d11 == canaryd); \
|
||||
ASSERT_TRUE(d12 == canaryd); \
|
||||
ASSERT_TRUE(d13 == canaryd); \
|
||||
ASSERT_TRUE(d14 == canaryd); \
|
||||
ASSERT_TRUE(d15 == canaryd); \
|
||||
ASSERT_TRUE(x19 == canaryx); \
|
||||
ASSERT_TRUE(x20 == canaryx); \
|
||||
ASSERT_TRUE(x21 == canaryx); \
|
||||
ASSERT_TRUE(x22 == canaryx); \
|
||||
ASSERT_TRUE(x23 == canaryx); \
|
||||
ASSERT_TRUE(x24 == canaryx); \
|
||||
ASSERT_TRUE(x25 == canaryx); \
|
||||
ASSERT_TRUE(x26 == canaryx); \
|
||||
ASSERT_TRUE(x27 == canaryx); \
|
||||
ASSERT_TRUE(x28 == canaryx);
|
||||
#else
|
||||
#define AARCH64_PUT_CANARY()
|
||||
#define AARCH64_CHECK_CANARY()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -83,6 +83,16 @@ typedef struct {
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASSERT_LT(VALUE1, VALUE2) \
|
||||
do { \
|
||||
int64_t value1__ = (int64_t)(VALUE1); \
|
||||
int64_t value2__ = (int64_t)(VALUE2); \
|
||||
if (!(value1__ < value2__)) { \
|
||||
RecordFailure(#VALUE1 #VALUE2, __FILE__); \
|
||||
Print("\nvalue is %d (0x%x).\nexpect %d (0x%x).\n", value1__, value1__, value2__, value2__); \
|
||||
goto EXIT; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASSERT_EQ_LOG(LOG, VALUE1, VALUE2) \
|
||||
do { \
|
||||
|
||||
@@ -261,14 +261,13 @@ void SDV_BSL_TIME_SYSTIME_API_TC001(void)
|
||||
|
||||
ret = BSL_SAL_SysTimeGet(&systime);
|
||||
ASSERT_TRUE(ret == BSL_SUCCESS);
|
||||
|
||||
int64_t timestamp = 0;
|
||||
ret = BSL_SAL_DateToUtcTimeConvert(&systime, ×tamp);
|
||||
|
||||
/* Get the current time. */
|
||||
int64_t curtime = time(NULL);
|
||||
|
||||
ASSERT_TRUE(curtime >= timestamp && curtime - 5 <= timestamp);
|
||||
int64_t timestamp = 0;
|
||||
ret = BSL_SAL_DateToUtcTimeConvert(&systime, ×tamp);
|
||||
ASSERT_LT(abs((int)(curtime - timestamp)), 5);
|
||||
EXIT:
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
*/
|
||||
|
||||
/* BEGIN_HEADER */
|
||||
|
||||
#include <pthread.h>
|
||||
#include "eal_md_local.h"
|
||||
#include "crypt_eal_md.h"
|
||||
#include "crypt_errno.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "crypt_sha2.h"
|
||||
#include "crypto_test_util.h"
|
||||
/* END_HEADER */
|
||||
|
||||
// 100 is greater than the digest length of all SHA algorithms.
|
||||
@@ -489,3 +490,586 @@ EXIT:
|
||||
CRYPT_EAL_MdFreeCtx(ctx);
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPTO_SHA256_MB_API_TC001
|
||||
* @title CRYPT_SHA256_MB API parameter validation test.
|
||||
* @precon nan
|
||||
* @brief
|
||||
* 1.Call CRYPT_SHA256_MBInit with NULL ctx, expected result 1.
|
||||
* 2.Call CRYPT_SHA256_MBInit with invalid num (!=2), expected result 2.
|
||||
* 3.Call CRYPT_SHA256_MBUpdate with NULL parameters, expected result 3.
|
||||
* 4.Call CRYPT_SHA256_MBFinal with NULL parameters, expected result 4.
|
||||
* 5.Call CRYPT_SHA256_MB with NULL parameters, expected result 5.
|
||||
* 6.Call CRYPT_SHA256_MB with valid parameters, expected result 6.
|
||||
* @expect
|
||||
* 1-5.Return error codes.
|
||||
* 6.Return CRYPT_SUCCESS.
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPTO_SHA256_MB_API_TC001(void)
|
||||
{
|
||||
#if !defined(__aarch64__) || !defined(HITLS_CRYPTO_SHA2_ASM) || !defined(HITLS_CRYPTO_SHA2_MB)
|
||||
SKIP_TEST();
|
||||
#else
|
||||
TestMemInit();
|
||||
uint8_t data1[64] = {0};
|
||||
uint8_t data2[64] = {0};
|
||||
const uint8_t *dataArr[2] = {data1, data2};
|
||||
uint8_t dgst1[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t *dgstArr[2] = {dgst1, dgst2};
|
||||
uint32_t outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
|
||||
/* Test invalid num (only support 2) */
|
||||
ASSERT_TRUE(CRYPT_SHA256_MBNewCtx(1) == NULL);
|
||||
ASSERT_TRUE(CRYPT_SHA256_MBNewCtx(3) == NULL);
|
||||
|
||||
CRYPT_SHA2_256_MB_Ctx *mbCtx = CRYPT_SHA256_MBNewCtx(2);
|
||||
ASSERT_TRUE(mbCtx != NULL);
|
||||
|
||||
/* Test invalid init parameters */
|
||||
ASSERT_EQ(CRYPT_SHA256_MBInit(NULL), CRYPT_NULL_INPUT);
|
||||
|
||||
/* Test valid init */
|
||||
ASSERT_EQ(CRYPT_SHA256_MBInit(mbCtx), CRYPT_SUCCESS);
|
||||
|
||||
/* Test valid update */
|
||||
uint32_t nbytesArr[2] = {64, 64};
|
||||
ASSERT_EQ(CRYPT_SHA256_MBUpdate(mbCtx, NULL, nbytesArr, 2), CRYPT_NULL_INPUT);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBUpdate(mbCtx, dataArr, nbytesArr, 1), CRYPT_NOT_SUPPORT);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBUpdate(mbCtx, dataArr, nbytesArr, 2), CRYPT_SUCCESS);
|
||||
|
||||
/* Test valid final */
|
||||
ASSERT_EQ(CRYPT_SHA256_MBFinal(mbCtx, NULL, &outlen, 2), CRYPT_NULL_INPUT);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBFinal(mbCtx, dgstArr, &outlen, 1), CRYPT_NOT_SUPPORT);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBFinal(mbCtx, dgstArr, &outlen, 2), CRYPT_SUCCESS);
|
||||
|
||||
/* Test one-shot API with NULL parameters */
|
||||
ASSERT_EQ(CRYPT_SHA256_MB(dataArr, 64, NULL, &outlen, 1), CRYPT_NOT_SUPPORT);
|
||||
|
||||
/* Test valid one-shot API */
|
||||
ASSERT_EQ(CRYPT_SHA256_MB(dataArr, 64, dgstArr, &outlen, 2), CRYPT_SUCCESS);
|
||||
|
||||
EXIT:
|
||||
CRYPT_SHA256_MBFreeCtx(mbCtx);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPTO_SHA256_MB_FUNC_TC001
|
||||
* @title CRYPT_SHA256_MB one-shot API test with same message.
|
||||
* @precon nan
|
||||
* @brief
|
||||
* 1.Prepare two identical messages and digest buffers, expected result 1.
|
||||
* 2.Call CRYPT_SHA256_MB to compute both hashes, expected result 2.
|
||||
* 3.Compare results with expected digest, expected result 3.
|
||||
* @expect
|
||||
* 1.Preparation successful.
|
||||
* 2.Function returns CRYPT_SUCCESS.
|
||||
* 3.Both digests match expected value.
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPTO_SHA256_MB_FUNC_TC001(Hex *msg, Hex *digest)
|
||||
{
|
||||
#if !defined(__aarch64__) || !defined(HITLS_CRYPTO_SHA2_ASM) || !defined(HITLS_CRYPTO_SHA2_MB)
|
||||
SKIP_TEST();
|
||||
(void)msg;
|
||||
(void)digest;
|
||||
#else
|
||||
TestMemInit();
|
||||
const uint8_t *dataArr[2] = {msg->x, msg->x};
|
||||
uint8_t dgst1[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t *dgstArr[2] = {dgst1, dgst2};
|
||||
uint32_t outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
|
||||
ASSERT_EQ(CRYPT_SHA256_MB(dataArr, msg->len, dgstArr, &outlen, 2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(outlen, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
ASSERT_COMPARE("SHA256_MB msg1", dgst1, CRYPT_SHA2_256_DIGESTSIZE, digest->x, digest->len);
|
||||
ASSERT_COMPARE("SHA256_MB msg2", dgst2, CRYPT_SHA2_256_DIGESTSIZE, digest->x, digest->len);
|
||||
|
||||
EXIT:
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPTO_SHA256_MB_FUNC_TC002
|
||||
* @title CRYPT_SHA256_MB Init/Update/Final workflow test.
|
||||
* @precon nan
|
||||
* @brief
|
||||
* 1.Call CRYPT_SHA256_MBInit to initialize contexts, expected result 1.
|
||||
* 2.Call CRYPT_SHA256_MBUpdate to process equal-length messages, expected result 2.
|
||||
* 3.Call CRYPT_SHA256_MBFinal to get digests, expected result 3.
|
||||
* 4.Compare results with expected digests, expected result 4.
|
||||
* @expect
|
||||
* 1-3.All functions return CRYPT_SUCCESS.
|
||||
* 4.Digests match expected values.
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPTO_SHA256_MB_FUNC_TC002(Hex *msg, Hex *digest)
|
||||
{
|
||||
#if !defined(__aarch64__) || !defined(HITLS_CRYPTO_SHA2_ASM) || !defined(HITLS_CRYPTO_SHA2_MB)
|
||||
SKIP_TEST();
|
||||
(void)msg;
|
||||
(void)digest;
|
||||
#else
|
||||
TestMemInit();
|
||||
const uint8_t *dataArr[2] = {msg->x, msg->x};
|
||||
uint8_t dgst1[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t *dgstArr[2] = {dgst1, dgst2};
|
||||
uint32_t outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
uint32_t nbytesArr[2] = {msg->len, msg->len};
|
||||
|
||||
CRYPT_SHA2_256_MB_Ctx *mbCtx = CRYPT_SHA256_MBNewCtx(2);
|
||||
ASSERT_TRUE(mbCtx != NULL);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBInit(mbCtx), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBUpdate(mbCtx, dataArr, nbytesArr, 2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBFinal(mbCtx, dgstArr, &outlen, 2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(outlen, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
|
||||
ASSERT_COMPARE("SHA256_MB msg1", dgst1, CRYPT_SHA2_256_DIGESTSIZE, digest->x, digest->len);
|
||||
ASSERT_COMPARE("SHA256_MB msg2", dgst2, CRYPT_SHA2_256_DIGESTSIZE, digest->x, digest->len);
|
||||
|
||||
EXIT:
|
||||
CRYPT_SHA256_MBFreeCtx(mbCtx);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPTO_SHA256_MB_FUNC_TC004
|
||||
* @title CRYPT_SHA256_MB multi-block length test.
|
||||
* @precon nan
|
||||
* @brief
|
||||
* 1.Generate two different messages of specified length, expected result 1.
|
||||
* 2.Compute hashes using CRYPT_SHA256_MB, expected result 2.
|
||||
* 3.Verify results match sequential SHA256 computation, expected result 3.
|
||||
* @expect
|
||||
* 1.Messages generated successfully.
|
||||
* 2.Function returns CRYPT_SUCCESS.
|
||||
* 3.Results match sequential computation for both messages.
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPTO_SHA256_MB_FUNC_TC004(int msgLen)
|
||||
{
|
||||
#if !defined(__aarch64__) || !defined(HITLS_CRYPTO_SHA2_ASM) || !defined(HITLS_CRYPTO_SHA2_MB)
|
||||
SKIP_TEST();
|
||||
(void)msgLen;
|
||||
#else
|
||||
TestMemInit();
|
||||
uint8_t *data1 = NULL;
|
||||
uint8_t *data2 = NULL;
|
||||
CRYPT_EAL_MdCTX *seqCtx1 = NULL;
|
||||
CRYPT_EAL_MdCTX *seqCtx2 = NULL;
|
||||
|
||||
/* Allocate and fill test data */
|
||||
data1 = (uint8_t *)malloc(msgLen);
|
||||
data2 = (uint8_t *)malloc(msgLen);
|
||||
ASSERT_TRUE(data1 != NULL && data2 != NULL);
|
||||
|
||||
for (int i = 0; i < msgLen; i++) {
|
||||
data1[i] = (uint8_t)(i & 0xFF);
|
||||
data2[i] = (uint8_t)((i * 3 + 7) & 0xFF);
|
||||
}
|
||||
|
||||
/* MB computation */
|
||||
const uint8_t *dataArr[2] = {data1, data2};
|
||||
uint8_t dgst1_mb[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2_mb[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t *dgstArr[2] = {dgst1_mb, dgst2_mb};
|
||||
uint32_t outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
|
||||
AARCH64_PUT_CANARY();
|
||||
ASSERT_EQ(CRYPT_SHA256_MB(dataArr, msgLen, dgstArr, &outlen, 2), CRYPT_SUCCESS);
|
||||
AARCH64_CHECK_CANARY();
|
||||
/* Sequential computation for verification */
|
||||
seqCtx1 = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256);
|
||||
seqCtx2 = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256);
|
||||
ASSERT_TRUE(seqCtx1 != NULL && seqCtx2 != NULL);
|
||||
|
||||
uint8_t dgst1_seq[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2_seq[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint32_t seqOutlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
|
||||
ASSERT_EQ(CRYPT_EAL_MdInit(seqCtx1), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx1, data1, msgLen), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdFinal(seqCtx1, dgst1_seq, &seqOutlen), CRYPT_SUCCESS);
|
||||
|
||||
seqOutlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
ASSERT_EQ(CRYPT_EAL_MdInit(seqCtx2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx2, data2, msgLen), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdFinal(seqCtx2, dgst2_seq, &seqOutlen), CRYPT_SUCCESS);
|
||||
|
||||
/* Compare results */
|
||||
ASSERT_COMPARE("MB vs seq msg1", dgst1_mb, CRYPT_SHA2_256_DIGESTSIZE,
|
||||
dgst1_seq, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
ASSERT_COMPARE("MB vs seq msg2", dgst2_mb, CRYPT_SHA2_256_DIGESTSIZE,
|
||||
dgst2_seq, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
|
||||
EXIT:
|
||||
free(data1);
|
||||
free(data2);
|
||||
CRYPT_EAL_MdFreeCtx(seqCtx1);
|
||||
CRYPT_EAL_MdFreeCtx(seqCtx2);
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPTO_SHA256_MB_FUNC_TC003
|
||||
* @title CRYPT_SHA256_MB multi-update test.
|
||||
* @precon nan
|
||||
* @brief
|
||||
* 1.Initialize MB contexts, expected result 1.
|
||||
* 2.Call Update multiple times with different data chunks, expected result 2.
|
||||
* 3.Finalize and compare with sequential SHA256, expected result 3.
|
||||
* @expect
|
||||
* 1-2.All operations return CRYPT_SUCCESS.
|
||||
* 3.Results match sequential computation.
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPTO_SHA256_MB_FUNC_TC003(void)
|
||||
{
|
||||
#if !defined(__aarch64__) || !defined(HITLS_CRYPTO_SHA2_ASM) || !defined(HITLS_CRYPTO_SHA2_MB)
|
||||
SKIP_TEST();
|
||||
#else
|
||||
TestMemInit();
|
||||
CRYPT_SHA2_256_MB_Ctx *mbCtx = CRYPT_SHA256_MBNewCtx(2);
|
||||
ASSERT_TRUE(mbCtx != NULL);
|
||||
|
||||
/* Prepare test data: split into chunks */
|
||||
uint8_t chunk1_1[32], chunk1_2[32], chunk1_3[16];
|
||||
uint8_t chunk2_1[32], chunk2_2[32], chunk2_3[16];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
chunk1_1[i] = (uint8_t)(i);
|
||||
chunk1_2[i] = (uint8_t)(i + 32);
|
||||
chunk2_1[i] = (uint8_t)(i * 2);
|
||||
chunk2_2[i] = (uint8_t)(i * 2 + 32);
|
||||
}
|
||||
for (int i = 0; i < 16; i++) {
|
||||
chunk1_3[i] = (uint8_t)(i + 64);
|
||||
chunk2_3[i] = (uint8_t)(i * 2 + 64);
|
||||
}
|
||||
|
||||
const uint8_t *dataArr1[2] = {chunk1_1, chunk2_1};
|
||||
const uint8_t *dataArr2[2] = {chunk1_2, chunk2_2};
|
||||
const uint8_t *dataArr3[2] = {chunk1_3, chunk2_3};
|
||||
|
||||
uint8_t dgst1[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t *dgstArr[2] = {dgst1, dgst2};
|
||||
uint32_t outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
uint32_t nbytesArr1[2] = {32, 32};
|
||||
uint32_t nbytesArr2[2] = {32, 32};
|
||||
uint32_t nbytesArr3[2] = {16, 16};
|
||||
|
||||
AARCH64_PUT_CANARY();
|
||||
/* MB computation with multiple updates */
|
||||
ASSERT_EQ(CRYPT_SHA256_MBInit(mbCtx), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBUpdate(mbCtx, dataArr1, nbytesArr1, 2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBUpdate(mbCtx, dataArr2, nbytesArr2, 2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBUpdate(mbCtx, dataArr3, nbytesArr3, 2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_SHA256_MBFinal(mbCtx, dgstArr, &outlen, 2), CRYPT_SUCCESS);
|
||||
|
||||
AARCH64_CHECK_CANARY();
|
||||
/* Sequential computation for verification */
|
||||
CRYPT_EAL_MdCTX *seqCtx1 = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256);
|
||||
CRYPT_EAL_MdCTX *seqCtx2 = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256);
|
||||
ASSERT_TRUE(seqCtx1 != NULL && seqCtx2 != NULL);
|
||||
|
||||
uint8_t seqDgst1[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t seqDgst2[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint32_t seqOutlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
|
||||
ASSERT_EQ(CRYPT_EAL_MdInit(seqCtx1), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx1, chunk1_1, 32), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx1, chunk1_2, 32), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx1, chunk1_3, 16), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdFinal(seqCtx1, seqDgst1, &seqOutlen), CRYPT_SUCCESS);
|
||||
|
||||
seqOutlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
ASSERT_EQ(CRYPT_EAL_MdInit(seqCtx2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx2, chunk2_1, 32), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx2, chunk2_2, 32), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx2, chunk2_3, 16), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdFinal(seqCtx2, seqDgst2, &seqOutlen), CRYPT_SUCCESS);
|
||||
|
||||
/* Compare results */
|
||||
ASSERT_COMPARE("MB vs seq msg1", dgst1, CRYPT_SHA2_256_DIGESTSIZE,
|
||||
seqDgst1, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
ASSERT_COMPARE("MB vs seq msg2", dgst2, CRYPT_SHA2_256_DIGESTSIZE,
|
||||
seqDgst2, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
|
||||
EXIT:
|
||||
CRYPT_SHA256_MBFreeCtx(mbCtx);
|
||||
CRYPT_EAL_MdFreeCtx(seqCtx1);
|
||||
CRYPT_EAL_MdFreeCtx(seqCtx2);
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPT_EAL_SHA256_MB_API_TC001
|
||||
* @title CRYPT_EAL_MdMB* API parameter validation test.
|
||||
* @precon nan
|
||||
* @brief
|
||||
* 1.Call CRYPT_EAL_MdMBNewCtx with num=0, expected result 1.
|
||||
* 2.Call CRYPT_EAL_MdMBNewCtx with invalid num (!=2), expected result 2.
|
||||
* 3.Call CRYPT_EAL_MdMBInit/Update/Final with NULL parameters, expected result 3.
|
||||
* @expect
|
||||
* 1-3.Return error codes / NULL pointers.
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPT_EAL_SHA256_MB_API_TC001(void)
|
||||
{
|
||||
#if !defined(HITLS_CRYPTO_MD_MB) || !defined(HITLS_CRYPTO_SHA2_MB)
|
||||
SKIP_TEST();
|
||||
#else
|
||||
TestMemInit();
|
||||
|
||||
ASSERT_TRUE(CRYPT_EAL_MdMBNewCtx(NULL, CRYPT_MD_SHA256_MB, 0) == NULL);
|
||||
ASSERT_TRUE(CRYPT_EAL_MdMBNewCtx(NULL, CRYPT_MD_SHA256_MB, 1) == NULL);
|
||||
ASSERT_TRUE(CRYPT_EAL_MdMBNewCtx(NULL, CRYPT_MD_SHA256_MB, 3) == NULL);
|
||||
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBInit(NULL), CRYPT_NULL_INPUT);
|
||||
uint32_t nbytesArr[2] = {1, 1};
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBUpdate(NULL, NULL, nbytesArr, 2), CRYPT_NULL_INPUT);
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBFinal(NULL, NULL, NULL, 2), CRYPT_NULL_INPUT);
|
||||
EXIT:
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPT_EAL_SHA256_MB_API_TC002
|
||||
* @title CRYPT_EAL_MdMB* boundary parameter combinations test.
|
||||
* @precon nan
|
||||
* @brief
|
||||
* 1.Create MB context and init it, expected result 1.
|
||||
* 2.Call CRYPT_EAL_MdMBUpdate with mismatched nbytes, expected result 2.
|
||||
* 3.Call CRYPT_EAL_MdMBUpdate with NULL lane data and non-zero nbytes, expected result 3.
|
||||
* 4.Call CRYPT_EAL_MdMBUpdate/Final with num=0, expected result 4.
|
||||
* 5.Call CRYPT_EAL_MdMBFinal with NULL digest lane, expected result 5.
|
||||
* 6.Call CRYPT_EAL_MdMBFinal with insufficient outlen, expected result 6.
|
||||
* @expect
|
||||
* 1.Return CRYPT_SUCCESS.
|
||||
* 2.Return CRYPT_NOT_SUPPORT.
|
||||
* 3.Return CRYPT_NULL_INPUT.
|
||||
* 4.Return CRYPT_NULL_INPUT.
|
||||
* 5.Return CRYPT_NULL_INPUT.
|
||||
* 6.Return CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH.
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPT_EAL_SHA256_MB_API_TC002(void)
|
||||
{
|
||||
#if !defined(__aarch64__) || !defined(HITLS_CRYPTO_SHA2_ASM) || !defined(HITLS_CRYPTO_SHA2_MB) || !defined(HITLS_CRYPTO_MD_MB)
|
||||
SKIP_TEST();
|
||||
#else
|
||||
TestMemInit();
|
||||
|
||||
CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdMBNewCtx(NULL, CRYPT_MD_SHA256_MB, 2);
|
||||
ASSERT_TRUE(ctx != NULL);
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBInit(ctx), CRYPT_SUCCESS);
|
||||
|
||||
uint8_t in1[1] = {0x01};
|
||||
uint8_t in2[1] = {0x02};
|
||||
const uint8_t *dataArr[2] = {in1, in2};
|
||||
|
||||
uint32_t nbytesMismatch[2] = {1, 2};
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBUpdate(ctx, dataArr, nbytesMismatch, 2), CRYPT_NOT_SUPPORT);
|
||||
|
||||
uint32_t nbytesValid[2] = {1, 1};
|
||||
const uint8_t *dataArrWithNull[2] = {NULL, in2};
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBUpdate(ctx, dataArrWithNull, nbytesValid, 2), CRYPT_NULL_INPUT);
|
||||
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBUpdate(ctx, dataArr, nbytesValid, 0), CRYPT_NULL_INPUT);
|
||||
|
||||
uint8_t dgst1[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t *dgstArrWithNull[2] = {NULL, dgst2};
|
||||
uint32_t outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBFinal(ctx, dgstArrWithNull, &outlen, 2), CRYPT_NULL_INPUT);
|
||||
|
||||
uint8_t *dgstArr[2] = {dgst1, dgst2};
|
||||
outlen = CRYPT_SHA2_256_DIGESTSIZE - 1;
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBFinal(ctx, dgstArr, &outlen, 2), CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH);
|
||||
|
||||
EXIT:
|
||||
CRYPT_EAL_MdMBFreeCtx(ctx);
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPT_EAL_SHA256_MB_FUNC_TC001
|
||||
* @title CRYPT_EAL_MdMB* Init/Update/Final workflow test.
|
||||
* @precon nan
|
||||
* @brief
|
||||
* 1.Create MB contexts using CRYPT_EAL_MdMBNewCtx, expected result 1.
|
||||
* 2.Call CRYPT_EAL_MdMBInit/Update/Final to compute two digests, expected result 2.
|
||||
* 3.Compare results with expected digest, expected result 3.
|
||||
* @expect
|
||||
* 1.Creation succeeds.
|
||||
* 2.All functions return CRYPT_SUCCESS.
|
||||
* 3.Both digests match expected value.
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPT_EAL_SHA256_MB_FUNC_TC001(Hex *msg, Hex *digest)
|
||||
{
|
||||
#if !defined(__aarch64__) || !defined(HITLS_CRYPTO_SHA2_ASM) || !defined(HITLS_CRYPTO_SHA2_MB) || !defined(HITLS_CRYPTO_MD_MB)
|
||||
SKIP_TEST();
|
||||
(void)msg;
|
||||
(void)digest;
|
||||
#else
|
||||
TestMemInit();
|
||||
|
||||
CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdMBNewCtx(NULL, CRYPT_MD_SHA256_MB, 2);
|
||||
ASSERT_TRUE(ctx != NULL);
|
||||
|
||||
const uint8_t *dataArr[2] = {msg->x, msg->x};
|
||||
uint32_t nbytesArr[2] = {msg->len, msg->len};
|
||||
uint8_t dgst1[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t *dgstArr[2] = {dgst1, dgst2};
|
||||
uint32_t outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBInit(ctx), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBUpdate(ctx, dataArr, nbytesArr, 2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBFinal(ctx, dgstArr, &outlen, 2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(outlen, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
|
||||
ASSERT_COMPARE("EAL_SHA256_MB msg1", dgst1, CRYPT_SHA2_256_DIGESTSIZE, digest->x, digest->len);
|
||||
ASSERT_COMPARE("EAL_SHA256_MB msg2", dgst2, CRYPT_SHA2_256_DIGESTSIZE, digest->x, digest->len);
|
||||
|
||||
EXIT:
|
||||
CRYPT_EAL_MdMBFreeCtx(ctx);
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002
|
||||
* @title CRYPT_EAL_MdMB* length boundary and multi-update test.
|
||||
* @precon nan
|
||||
* @brief
|
||||
* 1.Generate two different messages of specified length, expected result 1.
|
||||
* 2.Compute hashes using CRYPT_EAL_MdMB workflow with multiple updates, expected result 2.
|
||||
* 3.Verify results match sequential SHA256 computation, expected result 3.
|
||||
* @expect
|
||||
* 1.Messages generated successfully.
|
||||
* 2.All MB workflow functions return CRYPT_SUCCESS.
|
||||
* 3.Results match sequential computation for both messages.
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002(int msgLen)
|
||||
{
|
||||
#if !defined(__aarch64__) || !defined(HITLS_CRYPTO_SHA2_ASM) || !defined(HITLS_CRYPTO_SHA2_MB) || !defined(HITLS_CRYPTO_MD_MB)
|
||||
SKIP_TEST();
|
||||
(void)msgLen;
|
||||
#else
|
||||
TestMemInit();
|
||||
if (msgLen < 0) {
|
||||
SKIP_TEST();
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *data1 = NULL;
|
||||
uint8_t *data2 = NULL;
|
||||
CRYPT_EAL_MdCTX *mbCtx = NULL;
|
||||
CRYPT_EAL_MdCTX *seqCtx1 = NULL;
|
||||
CRYPT_EAL_MdCTX *seqCtx2 = NULL;
|
||||
|
||||
uint32_t allocLen = (msgLen == 0) ? 1u : (uint32_t)msgLen;
|
||||
data1 = (uint8_t *)malloc(allocLen);
|
||||
data2 = (uint8_t *)malloc(allocLen);
|
||||
ASSERT_TRUE(data1 != NULL && data2 != NULL);
|
||||
|
||||
for (int i = 0; i < msgLen; i++) {
|
||||
data1[i] = (uint8_t)(i & 0xFF);
|
||||
data2[i] = (uint8_t)((i * 3 + 7) & 0xFF);
|
||||
}
|
||||
|
||||
/* MB workflow computation */
|
||||
mbCtx = CRYPT_EAL_MdMBNewCtx(NULL, CRYPT_MD_SHA256_MB, 2);
|
||||
ASSERT_TRUE(mbCtx != NULL);
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBInit(mbCtx), CRYPT_SUCCESS);
|
||||
|
||||
/* Boundary: zero-length update should succeed */
|
||||
const uint8_t *dataArr0[2] = {data1, data2};
|
||||
uint32_t nbytesArr0[2] = {0, 0};
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBUpdate(mbCtx, dataArr0, nbytesArr0, 2), CRYPT_SUCCESS);
|
||||
|
||||
uint32_t offset = 0;
|
||||
if (msgLen > 0) {
|
||||
const uint8_t *dataArr1[2] = {data1, data2};
|
||||
uint32_t nbytesArr1[2] = {1, 1};
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBUpdate(mbCtx, dataArr1, nbytesArr1, 2), CRYPT_SUCCESS);
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
uint32_t remaining = (uint32_t)msgLen - offset;
|
||||
if (remaining > 0) {
|
||||
uint32_t chunkLen = (remaining > 63) ? 63 : remaining;
|
||||
const uint8_t *dataArr2[2] = {data1 + offset, data2 + offset};
|
||||
uint32_t nbytesArr2[2] = {chunkLen, chunkLen};
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBUpdate(mbCtx, dataArr2, nbytesArr2, 2), CRYPT_SUCCESS);
|
||||
offset += chunkLen;
|
||||
}
|
||||
|
||||
remaining = (uint32_t)msgLen - offset;
|
||||
if (remaining > 0) {
|
||||
const uint8_t *dataArr3[2] = {data1 + offset, data2 + offset};
|
||||
uint32_t nbytesArr3[2] = {remaining, remaining};
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBUpdate(mbCtx, dataArr3, nbytesArr3, 2), CRYPT_SUCCESS);
|
||||
}
|
||||
|
||||
uint8_t dgst1Mb[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2Mb[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t *dgstArr[2] = {dgst1Mb, dgst2Mb};
|
||||
uint32_t outlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
|
||||
AARCH64_PUT_CANARY();
|
||||
ASSERT_EQ(CRYPT_EAL_MdMBFinal(mbCtx, dgstArr, &outlen, 2), CRYPT_SUCCESS);
|
||||
AARCH64_CHECK_CANARY();
|
||||
ASSERT_EQ(outlen, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
|
||||
/* Sequential computation for verification */
|
||||
seqCtx1 = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256);
|
||||
seqCtx2 = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256);
|
||||
ASSERT_TRUE(seqCtx1 != NULL && seqCtx2 != NULL);
|
||||
|
||||
uint8_t dgst1Seq[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint8_t dgst2Seq[CRYPT_SHA2_256_DIGESTSIZE];
|
||||
uint32_t seqOutlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
|
||||
ASSERT_EQ(CRYPT_EAL_MdInit(seqCtx1), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx1, data1, (uint32_t)msgLen), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdFinal(seqCtx1, dgst1Seq, &seqOutlen), CRYPT_SUCCESS);
|
||||
|
||||
seqOutlen = CRYPT_SHA2_256_DIGESTSIZE;
|
||||
ASSERT_EQ(CRYPT_EAL_MdInit(seqCtx2), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdUpdate(seqCtx2, data2, (uint32_t)msgLen), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_MdFinal(seqCtx2, dgst2Seq, &seqOutlen), CRYPT_SUCCESS);
|
||||
|
||||
ASSERT_COMPARE("EAL_MB vs seq msg1", dgst1Mb, CRYPT_SHA2_256_DIGESTSIZE,
|
||||
dgst1Seq, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
ASSERT_COMPARE("EAL_MB vs seq msg2", dgst2Mb, CRYPT_SHA2_256_DIGESTSIZE,
|
||||
dgst2Seq, CRYPT_SHA2_256_DIGESTSIZE);
|
||||
|
||||
EXIT:
|
||||
free(data1);
|
||||
free(data2);
|
||||
CRYPT_EAL_MdMBFreeCtx(mbCtx);
|
||||
CRYPT_EAL_MdFreeCtx(seqCtx1);
|
||||
CRYPT_EAL_MdFreeCtx(seqCtx2);
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
@@ -132,3 +132,78 @@ SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA512:"6ba004fd176791efb381b862e29
|
||||
|
||||
SDV_CRYPTO_SHA2_DEFAULT_PROVIDER_FUNC_TC001 default provider
|
||||
SDV_CRYPTO_SHA2_DEFAULT_PROVIDER_FUNC_TC001:CRYPT_MD_SHA224:"a4bc10b1a62c96d459fbaf3a5aa3face73":"d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1"
|
||||
|
||||
CRYPT_SHA256_MB API parameter validation
|
||||
SDV_CRYPTO_SHA256_MB_API_TC001:
|
||||
|
||||
CRYPT_SHA256_MB one-shot API test with short messages
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC001:"d3":"28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1"
|
||||
|
||||
CRYPT_SHA256_MB one-shot API test with empty messages
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC001:"":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
|
||||
CRYPT_SHA256_MB single block (64 bytes)
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC004:64
|
||||
|
||||
CRYPT_SHA256_MB block boundary (56 bytes, need padding block)
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC004:56
|
||||
|
||||
CRYPT_SHA256_MB two blocks (120 bytes = 64+56)
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC004:120
|
||||
|
||||
CRYPT_SHA256_MB two blocks aligned (128 bytes = 64*2)
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC004:128
|
||||
|
||||
CRYPT_SHA256_MB three blocks (192 bytes = 64*3)
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC004:192
|
||||
|
||||
CRYPT_SHA256_MB large message (1024 bytes)
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC004:1024
|
||||
|
||||
CRYPT_SHA256_MB Init/Update/Final test
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC002:"3d83df37172c81afd0de115139fbf4390c22e098c5af4c5ab4852406510bc0e6cf741769f44430c5270fdae0cb849d71cbab":"99dc772e91ea02d9e421d552d61901016b9fd4ad2df4a8212c1ec5ba13893ab2"
|
||||
|
||||
CRYPT_SHA256_MB multi-update test
|
||||
SDV_CRYPTO_SHA256_MB_FUNC_TC003:
|
||||
|
||||
CRYPT_EAL_MdMB API parameter validation
|
||||
SDV_CRYPT_EAL_SHA256_MB_API_TC001:
|
||||
|
||||
CRYPT_EAL_MdMB boundary parameter combinations
|
||||
SDV_CRYPT_EAL_SHA256_MB_API_TC002:
|
||||
|
||||
CRYPT_EAL_MdMB Init/Update/Final test
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC001:"d3":"28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1"
|
||||
|
||||
CRYPT_EAL_MdMB length boundary (empty message)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:0
|
||||
|
||||
CRYPT_EAL_MdMB length boundary (1 byte)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:1
|
||||
|
||||
CRYPT_EAL_MdMB block boundary (55 bytes)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:55
|
||||
|
||||
CRYPT_EAL_MdMB block boundary (56 bytes, need padding block)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:56
|
||||
|
||||
CRYPT_EAL_MdMB block boundary (57 bytes)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:57
|
||||
|
||||
CRYPT_EAL_MdMB single block (64 bytes)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:64
|
||||
|
||||
CRYPT_EAL_MdMB one byte over block (65 bytes)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:65
|
||||
|
||||
CRYPT_EAL_MdMB two blocks (120 bytes = 64+56)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:120
|
||||
|
||||
CRYPT_EAL_MdMB two blocks aligned (128 bytes = 64*2)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:128
|
||||
|
||||
CRYPT_EAL_MdMB three blocks (192 bytes = 64*3)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:192
|
||||
|
||||
CRYPT_EAL_MdMB large message (1024 bytes)
|
||||
SDV_CRYPT_EAL_SHA256_MB_FUNC_TC002:1024
|
||||
|
||||
Reference in New Issue
Block a user