* 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 "crypt_eal_provider.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "bsl_obj.h"
#include "bsl_err.h"
#include "bsl_params.h"
#include "bsl_asn1_internal.h"
#include "bsl_obj_internal.h"
#include "crypt_codecskey.h"
#include "crypt_errno.h"
#include "crypt_params_key.h"
#include "crypt_eal_implprovider.h"
#include "hitls_type.h"
#include "crypt_params_key.h"
#include "provider_test_utils.h"
#define NEW_PARA_ALGID (BSL_CID_MAX + 5)
#define NEW_PKEY_ALGID (BSL_CID_MAX + 6)
#define NEW_SIGN_HASH_ALGID (BSL_CID_MAX + 7)
#define NEW_HASH_ALGID (BSL_CID_MAX + 8)
#define TEST_CRYPT_DEFAULT_SIGNLEN 68
#define UINT8_MAX_NUM 255
#define CRYPT_PARAM_NEW_KEY_BASE 3000
#define CRYPT_PARAM_NEW_KEY_PRVKEY (CRYPT_PARAM_NEW_KEY_BASE + 1)
#define CRYPT_PARAM_NEW_KEY_PUBKEY (CRYPT_PARAM_NEW_KEY_BASE + 2)
#define CRYPT_PARAM_NEW_KEY_GROUP (CRYPT_PARAM_NEW_KEY_BASE + 3)
typedef struct {
CRYPT_EAL_ProvMgrCtx *mgrCtxHandle;
} TestProvCtx;
typedef struct {
uint8_t prvkey[72];
uint32_t prvkeyLen;
uint8_t pubkey[256];
uint32_t pubkeyLen;
int32_t paraId;
} TestNewKeyCtx;
typedef struct {
CRYPT_EAL_ProvMgrCtx *provMgrCtx;
int32_t keyAlgId;
const char *outFormat;
const char *outType;
} TestNewAlgDer2KeyCtx;
static void RandFunc(uint8_t *randNum, uint32_t randLen)
{
for (uint32_t i = 0; i < randLen; i++) {
randNum[i] = (uint8_t)(rand() % UINT8_MAX_NUM);
}
}
void *TestNewKeyMgmtNewCtx(void *provCtx, int32_t algId)
{
(void)provCtx;
(void)algId;
TestNewKeyCtx *pkeyCtx = malloc(sizeof(TestNewKeyCtx));
if (pkeyCtx == NULL) {
return NULL;
}
return (void *)pkeyCtx;
}
static int32_t TestNewKeySetPara(TestNewKeyCtx *ctx, const BSL_Param *param)
{
if (ctx == NULL || param == NULL) {
return CRYPT_NULL_INPUT;
}
const BSL_Param *para = TestFindConstParam(param, CRYPT_PARAM_NEW_KEY_GROUP);
if (para != NULL) {
if (para->value == NULL || para->valueType != BSL_PARAM_TYPE_INT32 ||
para->valueLen != sizeof(int32_t)) {
return CRYPT_INVALID_ARG;
}
ctx->paraId = *((int32_t *)para->value);
}
return CRYPT_SUCCESS;
}
static int32_t TestNewKeyGenKey(TestNewKeyCtx *ctx)
{
if (ctx == NULL) {
return CRYPT_NULL_INPUT;
}
if (ctx->paraId != NEW_PARA_ALGID) {
return CRYPT_INVALID_ARG;
}
ctx->prvkeyLen = 66;
ctx->pubkeyLen = 143;
RandFunc(ctx->prvkey, ctx->prvkeyLen);
RandFunc(ctx->pubkey, ctx->pubkeyLen);
return CRYPT_SUCCESS;
}
static int32_t TestNewKeySetPrvKey(TestNewKeyCtx *ctx, const BSL_Param *para)
{
if (ctx == NULL || para == NULL) {
return CRYPT_NULL_INPUT;
}
const BSL_Param *prv = TestFindConstParam(para, CRYPT_PARAM_NEW_KEY_PRVKEY);
if (prv == NULL || prv->value == NULL || prv->valueLen == 0) {
return CRYPT_NULL_INPUT;
}
(void)memcpy(ctx->prvkey, prv->value, prv->valueLen);
ctx->prvkeyLen = prv->valueLen;
return CRYPT_SUCCESS;
}
static int32_t TestNewKeySetPubKey(TestNewKeyCtx *ctx, const BSL_Param *para)
{
if (ctx == NULL || para == NULL) {
return CRYPT_NULL_INPUT;
}
const BSL_Param *pub = TestFindConstParam(para, CRYPT_PARAM_NEW_KEY_PUBKEY);
if (pub == NULL) {
pub = TestFindConstParam(para, CRYPT_PARAM_PKEY_ENCODE_PUBKEY);
}
if (pub == NULL || pub->value == NULL || pub->valueLen == 0) {
return CRYPT_NULL_INPUT;
}
(void)memcpy(ctx->pubkey, pub->value, pub->valueLen);
ctx->pubkeyLen = pub->valueLen;
return CRYPT_SUCCESS;
}
static int32_t TestNewKeyGetPrvKey(TestNewKeyCtx *ctx, BSL_Param *para)
{
if (ctx == NULL || para == NULL) {
return CRYPT_NULL_INPUT;
}
BSL_Param *prv = TestFindParam(para, CRYPT_PARAM_NEW_KEY_PRVKEY);
if (prv == NULL) {
return CRYPT_NULL_INPUT;
}
if (prv->valueLen < ctx->prvkeyLen) {
return CRYPT_INVALID_ARG;
}
(void)memcpy(prv->value, ctx->prvkey, ctx->prvkeyLen);
prv->useLen = ctx->prvkeyLen;
return CRYPT_SUCCESS;
}
static int32_t TestNewKeyGetPubKey(TestNewKeyCtx *ctx, BSL_Param *para)
{
if (ctx == NULL || para == NULL) {
return CRYPT_NULL_INPUT;
}
BSL_Param *pub = TestFindParam(para, CRYPT_PARAM_NEW_KEY_PUBKEY);
if (pub == NULL) {
pub = TestFindParam(para, CRYPT_PARAM_PKEY_ENCODE_PUBKEY);
}
if (pub == NULL || pub->value == NULL || pub->valueLen == 0) {
return CRYPT_NULL_INPUT;
}
if (ctx->pubkey == NULL) {
return CRYPT_ECC_PKEY_ERR_EMPTY_KEY;
}
(void)memcpy(pub->value, ctx->pubkey, ctx->pubkeyLen);
pub->useLen = ctx->pubkeyLen;
return CRYPT_SUCCESS;
}
static int32_t TestNewKeySign(const TestNewKeyCtx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen,
uint8_t *sign, uint32_t *signLen)
{
if (ctx == NULL || data == NULL || sign == NULL || signLen == NULL) {
return CRYPT_NULL_INPUT;
}
if (*signLen < TEST_CRYPT_DEFAULT_SIGNLEN) {
return CRYPT_INVALID_ARG;
}
sign[0] = 0x30;
sign[1] = 0x42;
sign[2] = 0x02;
sign[3] = 0x40;
for (uint32_t i = 4; i < TEST_CRYPT_DEFAULT_SIGNLEN; i++) {
sign[i] = ctx->pubkey[(i - 4) % ctx->pubkeyLen];
}
*signLen = TEST_CRYPT_DEFAULT_SIGNLEN;
return CRYPT_SUCCESS;
}
static int32_t TestNewKeyVerify(const TestNewKeyCtx *ctx, int32_t algId,
const uint8_t *data, uint32_t dataLen,
const uint8_t *sign, uint32_t signLen)
{
if (ctx == NULL || data == NULL || sign == NULL) {
return CRYPT_NULL_INPUT;
}
if (signLen != TEST_CRYPT_DEFAULT_SIGNLEN) {
return CRYPT_INVALID_ARG;
}
if (sign[0] != 0x30 || sign[1] != 0x42) {
return CRYPT_ECDSA_VERIFY_FAIL;
}
if (sign[2] != 0x02 || sign[3] != 0x40) {
return CRYPT_ECDSA_VERIFY_FAIL;
}
for (uint32_t i = 4; i < TEST_CRYPT_DEFAULT_SIGNLEN; i++) {
if (sign[i] != ctx->pubkey[(i - 4) % ctx->pubkeyLen]) {
return CRYPT_ECDSA_VERIFY_FAIL;
}
}
return CRYPT_SUCCESS;
}
static void TestNewKeyFreeCtx(TestNewKeyCtx *ctx)
{
if (ctx != NULL) {
free(ctx);
}
}
static int32_t TestNewKeyCheck(const TestNewKeyCtx *ctx1, const TestNewKeyCtx *ctx2)
{
(void)ctx1;
(void)ctx2;
return CRYPT_SUCCESS;
}
static int32_t TestNewKeyCtrl(TestNewKeyCtx *ctx, int32_t cmd, void *val, uint32_t valLen)
{
if (ctx == NULL || val == NULL) {
return CRYPT_NULL_INPUT;
}
if (valLen != sizeof(uint32_t)) {
return CRYPT_INVALID_ARG;
}
switch (cmd) {
case CRYPT_CTRL_GET_SECBITS:
if (valLen != sizeof(uint32_t)) {
return CRYPT_INVALID_ARG;
}
*((uint32_t *)val) = 2048;
return CRYPT_SUCCESS;
case CRYPT_CTRL_GET_PARAID:
if (valLen != sizeof(uint32_t)) {
return CRYPT_INVALID_ARG;
}
*((uint32_t *)val) = NEW_PARA_ALGID;
return CRYPT_SUCCESS;
case CRYPT_CTRL_SET_PARA_BY_ID:
ctx->paraId = *((int32_t *)val);
return CRYPT_SUCCESS;
case CRYPT_CTRL_GET_SIGNLEN:
*((uint32_t *)val) = TEST_CRYPT_DEFAULT_SIGNLEN;
return CRYPT_SUCCESS;
default:
return CRYPT_NOT_SUPPORT;
}
}
static int32_t TestNewKeyImport(void *ctx, const BSL_Param *params)
{
TestNewKeyCtx *keyCtx = (TestNewKeyCtx *)ctx;
if (keyCtx == NULL || params == NULL) {
return CRYPT_NULL_INPUT;
}
int32_t ret = CRYPT_SUCCESS;
const BSL_Param *para = TestFindConstParam(params, CRYPT_PARAM_NEW_KEY_GROUP);
const BSL_Param *prv = TestFindConstParam(params, CRYPT_PARAM_NEW_KEY_PRVKEY);
const BSL_Param *pub = TestFindConstParam(params, CRYPT_PARAM_NEW_KEY_PUBKEY);
if (para != NULL) {
ret = TestNewKeySetPara(keyCtx, para);
if (ret != CRYPT_SUCCESS) {
return ret;
}
}
if (prv != NULL) {
ret = TestNewKeySetPrvKey(keyCtx, prv);
if (ret != CRYPT_SUCCESS) {
return ret;
}
}
if (pub != NULL) {
ret = TestNewKeySetPubKey(keyCtx, pub);
if (ret != CRYPT_SUCCESS) {
return ret;
}
}
return CRYPT_SUCCESS;
}
static void *TestNewKeyDupCtx(const void *ctx)
{
void *dest = malloc(sizeof(TestNewKeyCtx));
if (dest == NULL) {
return NULL;
}
(void)memcpy(dest, ctx, sizeof(TestNewKeyCtx));
return dest;
}
static int32_t TestNewKeyExport(void *ctx, BSL_Param *params)
{
(void)ctx;
(void)params;
return CRYPT_SUCCESS;
}
static int32_t TestNewKeyExch(const void *ctx, const void *pubCtx, uint8_t *out, uint32_t *outLen)
{
if (ctx == NULL || pubCtx == NULL || out == NULL || outLen == NULL) {
return CRYPT_NULL_INPUT;
}
const TestNewKeyCtx *prvKeyCtx = ctx;
const TestNewKeyCtx *pubKeyCtx = pubCtx;
int32_t len = pubKeyCtx->pubkeyLen < prvKeyCtx->pubkeyLen ? pubKeyCtx->pubkeyLen : prvKeyCtx->pubkeyLen;
for (uint32_t i = 0; i < len; i++) {
out[i] = (prvKeyCtx->pubkey[i] + pubKeyCtx->pubkey[i]) % 256;
}
*outLen = len;
return CRYPT_SUCCESS;
}
const CRYPT_EAL_Func g_testKeyMgmtNewKey[] = {
{CRYPT_EAL_IMPLPKEYMGMT_NEWCTX, (CRYPT_EAL_ImplPkeyMgmtNewCtx)TestNewKeyMgmtNewCtx},
{CRYPT_EAL_IMPLPKEYMGMT_SETPARAM, (CRYPT_EAL_ImplPkeyMgmtSetParam)TestNewKeySetPara},
{CRYPT_EAL_IMPLPKEYMGMT_GENKEY, (CRYPT_EAL_ImplPkeyMgmtGenKey)TestNewKeyGenKey},
{CRYPT_EAL_IMPLPKEYMGMT_SETPRV, (CRYPT_EAL_ImplPkeyMgmtSetPrv)TestNewKeySetPrvKey},
{CRYPT_EAL_IMPLPKEYMGMT_SETPUB, (CRYPT_EAL_ImplPkeyMgmtSetPub)TestNewKeySetPubKey},
{CRYPT_EAL_IMPLPKEYMGMT_GETPRV, (CRYPT_EAL_ImplPkeyMgmtGetPrv)TestNewKeyGetPrvKey},
{CRYPT_EAL_IMPLPKEYMGMT_GETPUB, (CRYPT_EAL_ImplPkeyMgmtGetPub)TestNewKeyGetPubKey},
{CRYPT_EAL_IMPLPKEYMGMT_DUPCTX, (CRYPT_EAL_ImplPkeyMgmtDupCtx)TestNewKeyDupCtx},
{CRYPT_EAL_IMPLPKEYMGMT_CTRL, (CRYPT_EAL_ImplPkeyMgmtCtrl)TestNewKeyCtrl},
{CRYPT_EAL_IMPLPKEYMGMT_IMPORT, (CRYPT_EAL_ImplPkeyMgmtImport)TestNewKeyImport},
{CRYPT_EAL_IMPLPKEYMGMT_EXPORT, (CRYPT_EAL_ImplPkeyMgmtExport)TestNewKeyExport},
{CRYPT_EAL_IMPLPKEYMGMT_CHECK, (CRYPT_EAL_ImplPkeyMgmtCheck)TestNewKeyCheck},
{CRYPT_EAL_IMPLPKEYMGMT_FREECTX, (CRYPT_EAL_ImplPkeyMgmtFreeCtx)TestNewKeyFreeCtx},
CRYPT_EAL_FUNC_END
};
const CRYPT_EAL_Func g_testSignNew[] = {
{CRYPT_EAL_IMPLPKEYSIGN_SIGN, (void *)TestNewKeySign},
{CRYPT_EAL_IMPLPKEYSIGN_VERIFY, (void *)TestNewKeyVerify},
CRYPT_EAL_FUNC_END
};
const CRYPT_EAL_Func g_testExchDh[] = {
{CRYPT_EAL_IMPLPKEYEXCH_EXCH, (CRYPT_EAL_ImplPkeyExch)TestNewKeyExch},
CRYPT_EAL_FUNC_END
};
static CRYPT_EAL_AlgInfo g_testKeyMgmt[] = {
{NEW_PKEY_ALGID, g_testKeyMgmtNewKey, "provider=provider_new_alg_test"},
CRYPT_EAL_ALGINFO_END
};
static CRYPT_EAL_AlgInfo g_testSign[] = {
{NEW_PKEY_ALGID, g_testSignNew, "provider=provider_new_alg_test"},
CRYPT_EAL_ALGINFO_END
};
static CRYPT_EAL_AlgInfo g_testKeyExch[] = {
{NEW_PKEY_ALGID, g_testExchDh, "provider=provider_new_alg_test"},
CRYPT_EAL_ALGINFO_END
};
static void *DECODER_NewAlgDer2Key_NewCtx(void *provCtx)
{
(void)provCtx;
TestNewAlgDer2KeyCtx *ctx = calloc(1, sizeof(TestNewAlgDer2KeyCtx));
if (ctx == NULL) {
return NULL;
}
ctx->outFormat = "OBJECT";
ctx->outType = "LOW_KEY";
ctx->keyAlgId = NEW_PKEY_ALGID;
return ctx;
}
static int32_t DECODER_NewAlgDer2Key_GetParam(void *ctx, void *param)
{
if (ctx == NULL || param == NULL) {
return CRYPT_NULL_INPUT;
}
TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
BSL_Param *param1 = TestFindParam(param, CRYPT_PARAM_DECODE_OUTPUT_TYPE);
if (param1 != NULL) {
if (param1->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
return CRYPT_INVALID_ARG;
}
param1->value = (void *)(uintptr_t)decoderCtx->outType;
}
BSL_Param *param2 = TestFindParam(param, CRYPT_PARAM_DECODE_OUTPUT_FORMAT);
if (param2 != NULL) {
if (param2->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
return CRYPT_INVALID_ARG;
}
param2->value = (void *)(uintptr_t)decoderCtx->outFormat;
}
return CRYPT_SUCCESS;
}
static int32_t DECODER_NewAlgDer2Key_SetParam(void *ctx, const void *param)
{
TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
if (decoderCtx == NULL || param == NULL) {
return CRYPT_NULL_INPUT;
}
const BSL_Param *input = TestFindConstParam(param, CRYPT_PARAM_DECODE_PROVIDER_CTX);
if (input != NULL) {
if (input->valueType != BSL_PARAM_TYPE_CTX_PTR || input->value == NULL) {
return CRYPT_INVALID_ARG;
}
decoderCtx->provMgrCtx = (CRYPT_EAL_ProvMgrCtx *)(uintptr_t)input->value;
}
return CRYPT_SUCCESS;
}
#define BSL_ASN1_TAG_NEW_ALG_PRIKEY_PARAM 0
static BSL_ASN1_TemplateItem g_newAlgPrvTempl[] = {
{BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0},
{BSL_ASN1_TAG_INTEGER, 0, 1},
{BSL_ASN1_TAG_OCTETSTRING, 0, 1},
{BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_NEW_ALG_PRIKEY_PARAM,
BSL_ASN1_FLAG_OPTIONAL, 1},
{BSL_ASN1_TAG_OBJECT_ID, 0, 2},
{BSL_ASN1_TAG_OCTETSTRING, 0, 1},
};
typedef enum {
CRYPT_NEW_ALG_PRV_VERSION_IDX = 0,
CRYPT_NEW_ALG_PRV_PRVKEY_IDX = 1,
CRYPT_NEW_ALG_PRV_PRIKEY_PARAM_IDX = 2,
CRYPT_NEW_ALG_PRV_PUBKEY_IDX = 3,
} CRYPT_NEW_ALG_PRV_TEMPL_IDX;
static int32_t GetParaId(uint8_t *octs, uint32_t octsLen)
{
BslOidString oidStr = {octsLen, (char *)octs, 0};
BslCid cid = BSL_OBJ_GetCID(&oidStr);
if (cid == BSL_CID_UNKNOWN) {
return CRYPT_PKEY_PARAID_MAX;
}
return (int32_t)cid;
}
static int32_t ProcNewAlgKeyPair(uint8_t *buff, uint32_t buffLen, TestNewKeyCtx *newAlgKey)
{
BSL_ASN1_Buffer asn1[CRYPT_NEW_ALG_PRV_PUBKEY_IDX + 1] = {0};
uint8_t *tmpBuff = buff;
uint32_t tmpBuffLen = buffLen;
BSL_ASN1_Template templ = {g_newAlgPrvTempl, sizeof(g_newAlgPrvTempl) / sizeof(g_newAlgPrvTempl[0])};
int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &tmpBuff, &tmpBuffLen, asn1,
CRYPT_NEW_ALG_PRV_PUBKEY_IDX + 1);
if (ret != CRYPT_SUCCESS) {
return ret;
}
const BSL_Param param1[2] = {
{CRYPT_PARAM_NEW_KEY_PRVKEY, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_NEW_ALG_PRV_PRVKEY_IDX].buff,
asn1[CRYPT_NEW_ALG_PRV_PRVKEY_IDX].len, 0},
BSL_PARAM_END
};
ret = TestNewKeySetPrvKey(newAlgKey, param1);
if (ret != CRYPT_SUCCESS) {
return ret;
}
const BSL_Param param2[2] = {
{CRYPT_PARAM_NEW_KEY_PUBKEY, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_NEW_ALG_PRV_PUBKEY_IDX].buff,
asn1[CRYPT_NEW_ALG_PRV_PUBKEY_IDX].len, 0},
BSL_PARAM_END
};
ret = TestNewKeySetPubKey(newAlgKey, param2);
if (ret != CRYPT_SUCCESS) {
return ret;
}
int32_t cid = GetParaId(asn1[CRYPT_NEW_ALG_PRV_PRIKEY_PARAM_IDX].buff, asn1[CRYPT_NEW_ALG_PRV_PRIKEY_PARAM_IDX].len);
if (cid != NEW_PARA_ALGID) {
return CRYPT_INVALID_ARG;
}
BSL_Param param[2] = {
{CRYPT_PARAM_NEW_KEY_GROUP, BSL_PARAM_TYPE_INT32, &cid, sizeof(cid), 0},
BSL_PARAM_END
};
return TestNewKeySetPara(newAlgKey, param);
}
static int32_t CRYPT_NewAlg_ParsePrikeyAsn1Buff(uint8_t *buffer, uint32_t bufferLen, void **newAlgPriKey)
{
if (buffer == NULL || bufferLen == 0 || newAlgPriKey == NULL) {
return CRYPT_NULL_INPUT;
}
TestNewKeyCtx *key = TestNewKeyMgmtNewCtx(NULL, NEW_PKEY_ALGID);
if (key == NULL) {
return CRYPT_MEM_ALLOC_FAIL;
}
int32_t ret = ProcNewAlgKeyPair(buffer, bufferLen, key);
if (ret != CRYPT_SUCCESS) {
TestNewKeyFreeCtx(key);
return ret;
}
*newAlgPriKey = key;
return CRYPT_SUCCESS;
}
static int32_t ConstructOutputParams(TestNewAlgDer2KeyCtx *decoderCtx, void *key, BSL_Param **outParam)
{
BSL_Param *result = calloc(7, sizeof(BSL_Param));
if (result == NULL) {
return CRYPT_MEM_ALLOC_FAIL;
}
int32_t ret = TestParamInitValue(&result[0], CRYPT_PARAM_DECODE_OBJECT_DATA, BSL_PARAM_TYPE_CTX_PTR, key, 0);
if (ret != CRYPT_SUCCESS) {
goto EXIT;
}
ret = TestParamInitValue(&result[1], CRYPT_PARAM_DECODE_OBJECT_TYPE, BSL_PARAM_TYPE_INT32, &decoderCtx->keyAlgId,
sizeof(decoderCtx->outType));
if (ret != CRYPT_SUCCESS) {
goto EXIT;
}
ret = TestParamInitValue(&result[2], CRYPT_PARAM_DECODE_PKEY_EXPORT_METHOD_FUNC, BSL_PARAM_TYPE_FUNC_PTR,
TestNewKeyExport, 0);
if (ret != CRYPT_SUCCESS) {
goto EXIT;
}
ret = TestParamInitValue(&result[3], CRYPT_PARAM_DECODE_PKEY_FREE_METHOD_FUNC, BSL_PARAM_TYPE_FUNC_PTR,
TestNewKeyFreeCtx, 0);
if (ret != CRYPT_SUCCESS) {
goto EXIT;
}
ret = TestParamInitValue(&result[4], CRYPT_PARAM_DECODE_PKEY_DUP_METHOD_FUNC, BSL_PARAM_TYPE_FUNC_PTR,
TestNewKeyDupCtx, 0);
if (ret != CRYPT_SUCCESS) {
goto EXIT;
}
ret = TestParamInitValue(&result[5], CRYPT_PARAM_DECODE_PROVIDER_CTX, BSL_PARAM_TYPE_CTX_PTR,
decoderCtx->provMgrCtx, 0);
if (ret != CRYPT_SUCCESS) {
goto EXIT;
}
*outParam = result;
return CRYPT_SUCCESS;
EXIT:
TestNewKeyFreeCtx(key);
free(result);
return ret;
}
static int32_t DECODER_NewAlgDer2Key_Decode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam)
{
if (ctx == NULL || inParam == NULL || outParam == NULL) {
return CRYPT_NULL_INPUT;
}
void *key = NULL;
TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
const BSL_Param *input = TestFindConstParam(inParam, CRYPT_PARAM_DECODE_BUFFER_DATA);
if (input == NULL) {
return CRYPT_NULL_INPUT;
}
if (input->value == NULL || input->valueLen == 0 || input->valueType != BSL_PARAM_TYPE_OCTETS) {
return CRYPT_INVALID_ARG;
}
int32_t ret = CRYPT_NewAlg_ParsePrikeyAsn1Buff(input->value, input->valueLen, &key);
if (ret != CRYPT_SUCCESS) {
return ret;
}
return ConstructOutputParams(decoderCtx, key, outParam);
}
static int32_t NewAlgKeySubKeyInfoCb(int32_t type, uint32_t idx, void *data, void *expVal)
{
(void)idx;
BSL_ASN1_Buffer *param = (BSL_ASN1_Buffer *)data;
switch (type) {
case BSL_ASN1_TYPE_GET_ANY_TAG: {
BslOidString oidStr = {param->len, (char *)param->buff, 0};
BslCid cid = BSL_OBJ_GetCID(&oidStr);
if (cid == NEW_PKEY_ALGID) {
*(uint8_t *)expVal = BSL_ASN1_TAG_OBJECT_ID;
} else {
*(uint8_t *)expVal = BSL_ASN1_TAG_NULL;
}
return CRYPT_SUCCESS;
}
default:
break;
}
return CRYPT_DECODE_ASN1_BUFF_FAILED;
}
static int32_t DECODER_NewAlgSubPubKeyDer2Key_Decode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam)
{
if (ctx == NULL || inParam == NULL || outParam == NULL) {
return CRYPT_NULL_INPUT;
}
TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
CRYPT_DECODE_SubPubkeyInfo subKeyInfo = {0};
const BSL_Param *input = TestFindConstParam(inParam, CRYPT_PARAM_DECODE_BUFFER_DATA);
if (input == NULL) {
return CRYPT_NULL_INPUT;
}
if (input->value == NULL || input->valueLen == 0 || input->valueType != BSL_PARAM_TYPE_OCTETS) {
return CRYPT_INVALID_ARG;
}
int32_t ret = CRYPT_DECODE_SubPubkey((uint8_t *)input->value, input->valueLen, NewAlgKeySubKeyInfoCb, &subKeyInfo, false);
if (ret != CRYPT_SUCCESS) {
return ret;
}
if (subKeyInfo.keyType != NEW_PKEY_ALGID) {
return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
}
TestNewKeyCtx *newAlgKey = TestNewKeyMgmtNewCtx(NULL, NEW_PKEY_ALGID);
if (newAlgKey == NULL) {
ret = CRYPT_MEM_ALLOC_FAIL;
goto EXIT;
}
int32_t cid = GetParaId(subKeyInfo.keyParam.buff, subKeyInfo.keyParam.len);
if (cid != NEW_PARA_ALGID) {
ret = CRYPT_INVALID_ARG;
goto EXIT;
}
const BSL_Param param2[2] = {
{CRYPT_PARAM_NEW_KEY_PUBKEY, BSL_PARAM_TYPE_OCTETS, subKeyInfo.pubKey.buff,
subKeyInfo.pubKey.len, 0},
BSL_PARAM_END
};
ret = TestNewKeySetPubKey(newAlgKey, param2);
if (ret != CRYPT_SUCCESS) {
goto EXIT;
}
ret = ConstructOutputParams(decoderCtx, newAlgKey, outParam);
if (ret != CRYPT_SUCCESS) {
goto EXIT;
}
return CRYPT_SUCCESS;
EXIT:
TestNewKeyFreeCtx(newAlgKey);
return ret;
}
static void DECODER_NewAlgDer2Key_FreeOutData(void *ctx, BSL_Param *outData)
{
TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
if (decoderCtx == NULL || outData == NULL) {
return;
}
BSL_Param *outKey = TestFindParam(outData, CRYPT_PARAM_DECODE_OBJECT_DATA);
if (outKey == NULL) {
return;
}
TestNewKeyFreeCtx(outKey->value);
BSL_SAL_Free(outData);
}
static void DECODER_NewAlgDer2Key_FreeCtx(void *ctx)
{
if (ctx == NULL) {
return;
}
TestNewAlgDer2KeyCtx *decoderCtx = (TestNewAlgDer2KeyCtx *)ctx;
free(decoderCtx);
}
static const CRYPT_EAL_Func g_testDer2NewAlgKey[] = {
{CRYPT_DECODER_IMPL_NEWCTX, (CRYPT_DECODER_IMPL_NewCtx)DECODER_NewAlgDer2Key_NewCtx},
{CRYPT_DECODER_IMPL_GETPARAM, (CRYPT_DECODER_IMPL_GetParam)DECODER_NewAlgDer2Key_GetParam},
{CRYPT_DECODER_IMPL_SETPARAM, (CRYPT_DECODER_IMPL_SetParam)DECODER_NewAlgDer2Key_SetParam},
{CRYPT_DECODER_IMPL_DECODE, (CRYPT_DECODER_IMPL_Decode)DECODER_NewAlgDer2Key_Decode},
{CRYPT_DECODER_IMPL_FREEOUTDATA, (CRYPT_DECODER_IMPL_FreeOutData)DECODER_NewAlgDer2Key_FreeOutData},
{CRYPT_DECODER_IMPL_FREECTX, (CRYPT_DECODER_IMPL_FreeCtx)DECODER_NewAlgDer2Key_FreeCtx},
CRYPT_EAL_FUNC_END
};
static const CRYPT_EAL_Func g_testSubPubKeyDer2NewAlgKey[] = {
{CRYPT_DECODER_IMPL_NEWCTX, (CRYPT_DECODER_IMPL_NewCtx)DECODER_NewAlgDer2Key_NewCtx},
{CRYPT_DECODER_IMPL_GETPARAM, (CRYPT_DECODER_IMPL_GetParam)DECODER_NewAlgDer2Key_GetParam},
{CRYPT_DECODER_IMPL_SETPARAM, (CRYPT_DECODER_IMPL_SetParam)DECODER_NewAlgDer2Key_SetParam},
{CRYPT_DECODER_IMPL_DECODE, (CRYPT_DECODER_IMPL_Decode)DECODER_NewAlgSubPubKeyDer2Key_Decode},
{CRYPT_DECODER_IMPL_FREEOUTDATA, (CRYPT_DECODER_IMPL_FreeOutData)DECODER_NewAlgDer2Key_FreeOutData},
{CRYPT_DECODER_IMPL_FREECTX, (CRYPT_DECODER_IMPL_FreeCtx)DECODER_NewAlgDer2Key_FreeCtx},
CRYPT_EAL_FUNC_END
};
static CRYPT_EAL_AlgInfo g_testDecoder[] = {
{NEW_PKEY_ALGID, g_testDer2NewAlgKey, "provider=provider_new_alg_test, inFormat=ASN1, inType=CRYPT_PKEY_NEW_ALG, outFormat=OBJECT, outType=LOW_KEY"},
{NEW_PKEY_ALGID, g_testSubPubKeyDer2NewAlgKey, "provider=provider_new_alg_test, inFormat=ASN1, inType=PUBKEY_SUBKEY_WITHOUT_SEQ, outFormat=OBJECT, outType=LOW_KEY"},
CRYPT_EAL_ALGINFO_END
};
static int32_t TestProvQuery(void *provCtx, int32_t operaId, CRYPT_EAL_AlgInfo **algInfos)
{
(void)provCtx;
int32_t ret = CRYPT_SUCCESS;
switch (operaId) {
case CRYPT_EAL_OPERAID_KEYMGMT:
*algInfos = g_testKeyMgmt;
break;
case CRYPT_EAL_OPERAID_SIGN:
*algInfos = g_testSign;
break;
case CRYPT_EAL_OPERAID_KEYEXCH:
*algInfos = g_testKeyExch;
break;
case CRYPT_EAL_OPERAID_DECODER:
*algInfos = g_testDecoder;
break;
default:
return CRYPT_NOT_SUPPORT;
}
return CRYPT_SUCCESS;
}
static int32_t TestProvFree(void *provCtx)
{
if (provCtx != NULL) {
free(provCtx);
}
return CRYPT_SUCCESS;
}
static const Provider_Group g_tlsGroupInfo[] = {
{
"test_new_group_with_new_key_type",
NEW_PARA_ALGID,
NEW_PKEY_ALGID,
1024,
479,
143,
143,
0,
TLS12_VERSION_BIT | TLS13_VERSION_BIT,
false
}
};
static int32_t TestCryptGetSigAlgCaps(CRYPT_EAL_ProcessFuncCb cb, void *args)
{
if (cb == NULL) {
return CRYPT_NULL_INPUT;
}
uint16_t signatureScheme = 24444;
int32_t keyType = NEW_PKEY_ALGID;
int32_t paraId = NEW_PARA_ALGID;
int32_t signHashAlgId = NEW_SIGN_HASH_ALGID;
int32_t signAlgId = NEW_PKEY_ALGID;
int32_t hashAlgId = NEW_HASH_ALGID;
int32_t secBits = 1024;
uint32_t certVersionBits = TLS12_VERSION_BIT | TLS13_VERSION_BIT;
uint32_t chainVersionBits = TLS12_VERSION_BIT | TLS13_VERSION_BIT;
BSL_Param param[] = {
{
CRYPT_PARAM_CAP_TLS_SIGNALG_IANA_SIGN_NAME,
BSL_PARAM_TYPE_OCTETS_PTR,
(void *)(uintptr_t)"test_new_sign_alg_name_with_new_key_type",
(uint32_t)strlen("test_new_sign_alg_name_with_new_key_type")
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_IANA_SIGN_ID,
BSL_PARAM_TYPE_UINT16,
(void *)(uintptr_t)&(signatureScheme),
sizeof(uint16_t)
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_KEY_TYPE,
BSL_PARAM_TYPE_INT32,
(void *)(uintptr_t)&(keyType),
sizeof(keyType)
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_KEY_TYPE_OID,
BSL_PARAM_TYPE_OCTETS_PTR,
(void *)(uintptr_t)"\150\40\66\77\57",
(uint32_t)strlen("\150\40\66\77\57")
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_KEY_TYPE_NAME,
BSL_PARAM_TYPE_OCTETS_PTR,
(void *)(uintptr_t)"test_new_key_type",
(uint32_t)strlen("test_new_key_type")
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_PARA_ID,
BSL_PARAM_TYPE_INT32,
(void *)(uintptr_t)&(paraId),
sizeof(paraId)
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_PARA_OID,
BSL_PARAM_TYPE_OCTETS_PTR,
(void *)(uintptr_t)"\150\40\66\77\56",
(uint32_t)strlen("\150\40\66\77\56")
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_PARA_NAME,
BSL_PARAM_TYPE_OCTETS_PTR,
(void *)(uintptr_t)"test_new_para_name",
(uint32_t)strlen("test_new_para_name")
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_SIGNWITHMD_ID,
BSL_PARAM_TYPE_INT32,
(void *)(uintptr_t)&(signHashAlgId),
sizeof(signHashAlgId)
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_SIGNWITHMD_OID,
BSL_PARAM_TYPE_OCTETS_PTR,
(void *)(uintptr_t)"\150\40\66\77\55",
(uint32_t)strlen("\150\40\66\77\55")
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_SIGNWITHMD_NAME,
BSL_PARAM_TYPE_OCTETS_PTR,
(void *)(uintptr_t)"test_new_sign_with_md_name",
(uint32_t)strlen("test_new_sign_with_md_name")
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_SIGN_ID,
BSL_PARAM_TYPE_INT32,
(void *)(uintptr_t)&(signAlgId),
sizeof(signAlgId)
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_MD_ID,
BSL_PARAM_TYPE_INT32,
(void *)(uintptr_t)&(hashAlgId),
sizeof(hashAlgId)
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_MD_OID,
BSL_PARAM_TYPE_OCTETS_PTR,
(void *)(uintptr_t)"\150\40\66\71\65",
(uint32_t)strlen("\150\40\66\71\65")
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_MD_NAME,
BSL_PARAM_TYPE_OCTETS_PTR,
(void *)(uintptr_t)"test_new_md_name",
(uint32_t)strlen("test_new_md_name")
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_SEC_BITS,
BSL_PARAM_TYPE_INT32,
(void *)(uintptr_t)&(secBits),
sizeof(secBits)
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_CHAIN_VERSION_BITS,
BSL_PARAM_TYPE_UINT32,
(void *)(uintptr_t)&(chainVersionBits),
sizeof(chainVersionBits)
},
{
CRYPT_PARAM_CAP_TLS_SIGNALG_CERT_VERSION_BITS,
BSL_PARAM_TYPE_UINT32,
(void *)(uintptr_t)&(certVersionBits),
sizeof(certVersionBits)
}
};
return cb(param, args);
}
static int32_t TestProvGetCaps(void *provCtx, int32_t cmd, CRYPT_EAL_ProcessFuncCb cb, void *args)
{
switch (cmd) {
case CRYPT_EAL_GET_GROUP_CAP:
return TestCryptGetGroupCaps(g_tlsGroupInfo, sizeof(g_tlsGroupInfo) / sizeof(g_tlsGroupInfo[0]), cb, args);
case CRYPT_EAL_GET_SIGALG_CAP:
return TestCryptGetSigAlgCaps(cb, args);
default:
return CRYPT_NOT_SUPPORT;
}
}
static CRYPT_EAL_Func g_testProvOutFuncs[] = {
{CRYPT_EAL_PROVCB_QUERY, TestProvQuery},
{CRYPT_EAL_PROVCB_FREE, TestProvFree},
{CRYPT_EAL_PROVCB_CTRL, NULL},
{CRYPT_EAL_PROVCB_GETCAPS, TestProvGetCaps},
CRYPT_EAL_FUNC_END
};
int32_t CRYPT_EAL_ProviderInit(CRYPT_EAL_ProvMgrCtx *mgrCtx, BSL_Param *param,
CRYPT_EAL_Func *capFuncs, CRYPT_EAL_Func **outFuncs,
void **provCtx)
{
if (mgrCtx == NULL || capFuncs == NULL || outFuncs == NULL || provCtx == NULL) {
return CRYPT_NULL_INPUT;
}
TestProvCtx *ctx = malloc(sizeof(TestProvCtx));
if (ctx == NULL) {
return CRYPT_MEM_ALLOC_FAIL;
}
ctx->mgrCtxHandle = mgrCtx;
*provCtx = ctx;
*outFuncs = g_testProvOutFuncs;
return CRYPT_SUCCESS;
}