* 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 "hitls_build.h"
#if defined(HITLS_CRYPTO_KEY_DECODE_CHAIN) && defined(HITLS_CRYPTO_PROVIDER)
#include <string.h>
#include <stdbool.h>
#ifdef HITLS_CRYPTO_PROVIDER
#include "crypt_eal_implprovider.h"
#include "crypt_default_provderimpl.h"
#include "crypt_provider_local.h"
#endif
#include "crypt_eal_pkey.h"
#include "crypt_algid.h"
#ifdef HITLS_CRYPTO_RSA
#include "crypt_rsa.h"
#endif
#ifdef HITLS_CRYPTO_ECDSA
#include "crypt_ecdsa.h"
#endif
#ifdef HITLS_CRYPTO_SM2
#include "crypt_sm2.h"
#endif
#if defined(HITLS_CRYPTO_ED25519) || defined(HITLS_CRYPTO_X25519)
#include "crypt_curve25519.h"
#endif
#ifdef HITLS_CRYPTO_MLDSA
#include "crypt_mldsa.h"
#endif
#ifdef HITLS_CRYPTO_COMPOSITE
#include "crypt_composite.h"
#endif
#if defined(HITLS_CRYPTO_XMSS) || defined(HITLS_CRYPTO_XMSSMT)
#include "crypt_xmss.h"
#endif
#include "eal_pkey.h"
#include "crypt_errno.h"
#include "bsl_sal.h"
#include "bsl_obj.h"
#include "bsl_err_internal.h"
#include "crypt_params_key.h"
#include "crypt_codecskey_local.h"
#include "crypt_decoder_local.h"
#include "crypt_decoder.h"
#define PKEY_MAX_PARAM_NUM 20
#if defined(HITLS_CRYPTO_RSA) || defined(HITLS_CRYPTO_ECDSA) || defined(HITLS_CRYPTO_SM2) || \
defined(HITLS_CRYPTO_ED25519) || defined(HITLS_CRYPTO_MLDSA) || defined(HITLS_CRYPTO_XMSS) || \
defined(HITLS_CRYPTO_X25519)
typedef struct {
CRYPT_EAL_ProvMgrCtx *provMgrCtx;
EAL_PkeyUnitaryMethod method;
int32_t keyAlgId;
const char *outFormat;
const char *outType;
} DECODER_Der2KeyCtx;
DECODER_Der2KeyCtx *DECODER_DER2KEY_NewCtx(void *provCtx)
{
(void)provCtx;
DECODER_Der2KeyCtx *ctx = (DECODER_Der2KeyCtx *)BSL_SAL_Calloc(1, sizeof(DECODER_Der2KeyCtx));
if (ctx == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
return NULL;
}
ctx->outFormat = "OBJECT";
ctx->outType = "LOW_KEY";
return ctx;
}
#define DECODER_DEFINE_DER2KEY_NEW_CTX(keyType, keyId, keyMethod, asyCipherMethod, exchMethod, signMethod, kemMethod) \
void *DECODER_##keyType##Der2KeyNewCtx(void *provCtx) \
{ \
CRYPT_EAL_AsyAlgFuncsInfo funcs = {NULL, asyCipherMethod, exchMethod, signMethod, kemMethod, keyMethod}; \
DECODER_Der2KeyCtx *ctx = DECODER_DER2KEY_NewCtx(provCtx); \
if (ctx == NULL) { \
return NULL; \
} \
int32_t ret = CRYPT_EAL_SetPkeyMethod(&ctx->method, &funcs); \
if (ret != CRYPT_SUCCESS) { \
DECODER_DER2KEY_FreeCtx(ctx); \
return NULL; \
} \
ctx->keyAlgId = keyId; \
return ctx; \
}
int32_t DECODER_CommonGetParam(const DECODER_CommonCtx *commonCtx, BSL_Param *param)
{
if (commonCtx == NULL || param == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
BSL_Param *param1 = BSL_PARAM_FindParam(param, CRYPT_PARAM_DECODE_OUTPUT_TYPE);
if (param1 != NULL) {
if (param1->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
return CRYPT_INVALID_ARG;
}
param1->value = (void *)(uintptr_t)commonCtx->outType;
}
BSL_Param *param2 = BSL_PARAM_FindParam(param, CRYPT_PARAM_DECODE_OUTPUT_FORMAT);
if (param2 != NULL) {
if (param2->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
return CRYPT_INVALID_ARG;
}
param2->value = (void *)(uintptr_t)commonCtx->outFormat;
}
return CRYPT_SUCCESS;
}
int32_t DECODER_DER2KEY_GetParam(void *ctx, BSL_Param *param)
{
DECODER_Der2KeyCtx *decoderCtx = (DECODER_Der2KeyCtx *)ctx;
if (decoderCtx == NULL || param == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
DECODER_CommonCtx commonCtx = {
.outFormat = decoderCtx->outFormat,
.outType = decoderCtx->outType
};
return DECODER_CommonGetParam(&commonCtx, param);
}
int32_t DECODER_DER2KEY_SetParam(void *ctx, const BSL_Param *param)
{
DECODER_Der2KeyCtx *decoderCtx = (DECODER_Der2KeyCtx *)ctx;
if (decoderCtx == NULL || param == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
const BSL_Param *input = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_DECODE_PROVIDER_CTX);
if (input != NULL) {
if (input->valueType != BSL_PARAM_TYPE_CTX_PTR || input->value == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
return CRYPT_INVALID_ARG;
}
decoderCtx->provMgrCtx = (CRYPT_EAL_ProvMgrCtx *)(uintptr_t)input->value;
}
return CRYPT_SUCCESS;
}
static int32_t CheckParams(DECODER_Der2KeyCtx *decoderCtx, const BSL_Param *inParam, BSL_Param **outParam,
BSL_Buffer *asn1Encode)
{
if (decoderCtx == NULL || inParam == NULL || outParam == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
const BSL_Param *input = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_BUFFER_DATA);
if (input == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
if (input->value == NULL || input->valueLen == 0 || input->valueType != BSL_PARAM_TYPE_OCTETS) {
BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
return CRYPT_INVALID_ARG;
}
asn1Encode->data = (uint8_t *)(uintptr_t)input->value;
asn1Encode->dataLen = input->valueLen;
return CRYPT_SUCCESS;
}
#define DECODER_CHECK_PARAMS(ctx, inParam, outParam) \
void *key = NULL; \
BSL_Buffer asn1Encode = {0}; \
DECODER_Der2KeyCtx *decoderCtx = (DECODER_Der2KeyCtx *)ctx; \
int32_t ret = CheckParams(decoderCtx, inParam, outParam, &asn1Encode); \
if (ret != CRYPT_SUCCESS) { \
BSL_ERR_PUSH_ERROR(ret); \
return ret; \
}
static int32_t ConstructOutputParams(DECODER_Der2KeyCtx *decoderCtx, void *key, BSL_Param **outParam)
{
int32_t ret;
BSL_Param *result = BSL_SAL_Calloc(7, sizeof(BSL_Param));
if (result == NULL) {
ret = CRYPT_MEM_ALLOC_FAIL;
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
goto EXIT;
}
ret = BSL_PARAM_InitValue(&result[0], CRYPT_PARAM_DECODE_OBJECT_DATA, BSL_PARAM_TYPE_CTX_PTR, key, 0);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
goto EXIT;
}
ret = BSL_PARAM_InitValue(&result[1], CRYPT_PARAM_DECODE_OBJECT_TYPE, BSL_PARAM_TYPE_INT32, &decoderCtx->keyAlgId,
sizeof(int32_t));
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
goto EXIT;
}
ret = BSL_PARAM_InitValue(&result[2], CRYPT_PARAM_DECODE_PKEY_EXPORT_METHOD_FUNC, BSL_PARAM_TYPE_FUNC_PTR,
decoderCtx->method.export, 0);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
goto EXIT;
}
ret = BSL_PARAM_InitValue(&result[3], CRYPT_PARAM_DECODE_PKEY_FREE_METHOD_FUNC, BSL_PARAM_TYPE_FUNC_PTR,
decoderCtx->method.freeCtx, 0);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
goto EXIT;
}
ret = BSL_PARAM_InitValue(&result[4], CRYPT_PARAM_DECODE_PKEY_DUP_METHOD_FUNC, BSL_PARAM_TYPE_FUNC_PTR,
decoderCtx->method.dupCtx, 0);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
goto EXIT;
}
ret = BSL_PARAM_InitValue(&result[5], CRYPT_PARAM_DECODE_PROVIDER_CTX, BSL_PARAM_TYPE_CTX_PTR,
decoderCtx->provMgrCtx, 0);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
goto EXIT;
}
*outParam = result;
return CRYPT_SUCCESS;
EXIT:
if (decoderCtx->method.freeCtx != NULL) {
decoderCtx->method.freeCtx(key);
}
BSL_SAL_Free(result);
return ret;
}
#define DECODER_DEFINE_PRVKEY_DER2KEY_DECODE(keyType, keyStructName, parseFunc) \
int32_t DECODER_##keyType##PrvKeyDer2KeyDecode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam) \
{ \
DECODER_CHECK_PARAMS(ctx, inParam, outParam); \
ret = parseFunc(decoderCtx->provMgrCtx->libCtx, asn1Encode.data, asn1Encode.dataLen, NULL, \
(keyStructName **)&key); \
if (ret != CRYPT_SUCCESS) { \
BSL_ERR_PUSH_ERROR(ret); \
return ret; \
} \
return ConstructOutputParams(decoderCtx, key, outParam); \
}
#define DECODER_DEFINE_PUBKEY_DER2KEY_DECODE(keyType, keyStructName, parseFunc) \
int32_t DECODER_##keyType##PubKeyDer2KeyDecode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam) \
{ \
DECODER_CHECK_PARAMS(ctx, inParam, outParam); \
ret = parseFunc(decoderCtx->provMgrCtx->libCtx, asn1Encode.data, asn1Encode.dataLen, NULL, \
(keyStructName **)&key, BSL_CID_UNKNOWN); \
if (ret != CRYPT_SUCCESS) { \
BSL_ERR_PUSH_ERROR(ret); \
return ret; \
} \
return ConstructOutputParams(decoderCtx, key, outParam); \
}
#define DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(keyType, keyStructName, parseFunc) \
int32_t DECODER_##keyType##SubPubKeyDer2KeyDecode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam) \
{ \
DECODER_CHECK_PARAMS(ctx, inParam, outParam) \
ret = parseFunc(decoderCtx->provMgrCtx->libCtx, asn1Encode.data, asn1Encode.dataLen, \
(keyStructName **)&key, true); \
if (ret != CRYPT_SUCCESS) { \
BSL_ERR_PUSH_ERROR(ret); \
return ret; \
} \
return ConstructOutputParams(decoderCtx, key, outParam); \
}
#define DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(keyType, keyStructName, parseFunc) \
int32_t DECODER_##keyType##SubPubKeyWithOutSeqDer2KeyDecode(void *ctx, const BSL_Param *inParam, \
BSL_Param **outParam) \
{ \
DECODER_CHECK_PARAMS(ctx, inParam, outParam) \
ret = parseFunc(decoderCtx->provMgrCtx->libCtx, asn1Encode.data, asn1Encode.dataLen, (keyStructName **)&key, \
false); \
if (ret != CRYPT_SUCCESS) { \
BSL_ERR_PUSH_ERROR(ret); \
return ret; \
} \
return ConstructOutputParams(decoderCtx, key, outParam); \
}
#define DECODER_DEFINE_PKCS8_DECODE(keyType, keyStructName, parseFunc) \
int32_t DECODER_##keyType##Pkcs8Der2KeyDecode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam) \
{ \
DECODER_CHECK_PARAMS(ctx, inParam, outParam) \
ret = parseFunc(decoderCtx->provMgrCtx->libCtx, asn1Encode.data, asn1Encode.dataLen, (keyStructName **)&key); \
if (ret != CRYPT_SUCCESS) { \
BSL_ERR_PUSH_ERROR(ret); \
return ret; \
} \
return ConstructOutputParams(decoderCtx, key, outParam); \
}
void DECODER_DER2KEY_FreeOutData(void *ctx, BSL_Param *outParam)
{
DECODER_Der2KeyCtx *decoderCtx = ctx;
if (decoderCtx == NULL || outParam == NULL) {
return;
}
if (decoderCtx->method.freeCtx == NULL) {
return;
}
BSL_Param *outKey = BSL_PARAM_FindParam(outParam, CRYPT_PARAM_DECODE_OBJECT_DATA);
if (outKey == NULL) {
return;
}
decoderCtx->method.freeCtx(outKey->value);
BSL_SAL_Free(outParam);
}
void DECODER_DER2KEY_FreeCtx(void *ctx)
{
if (ctx != NULL) {
BSL_SAL_Free(ctx);
}
}
#endif
#ifdef HITLS_CRYPTO_PROVIDER
#ifdef HITLS_CRYPTO_RSA
DECODER_DEFINE_DER2KEY_NEW_CTX(Rsa, CRYPT_PKEY_RSA, g_defEalKeyMgmtRsa, g_defEalAsymCipherRsa, NULL, \
g_defEalSignRsa, NULL)
#endif
#ifdef HITLS_CRYPTO_ECDSA
DECODER_DEFINE_DER2KEY_NEW_CTX(Ecdsa, CRYPT_PKEY_ECDSA, g_defEalKeyMgmtEcdsa, NULL, NULL, g_defEalSignEcdsa, NULL)
#endif
#ifdef HITLS_CRYPTO_SM2
DECODER_DEFINE_DER2KEY_NEW_CTX(Sm2, CRYPT_PKEY_SM2, g_defEalKeyMgmtSm2, g_defEalAsymCipherSm2, g_defEalExchSm2, \
g_defEalSignSm2, NULL)
#endif
#ifdef HITLS_CRYPTO_ED25519
DECODER_DEFINE_DER2KEY_NEW_CTX(Ed25519, CRYPT_PKEY_ED25519, g_defEalKeyMgmtEd25519, NULL, NULL, \
g_defEalSignEd25519, NULL)
#endif
#ifdef HITLS_CRYPTO_X25519
DECODER_DEFINE_DER2KEY_NEW_CTX(X25519, CRYPT_PKEY_X25519, g_defEalKeyMgmtX25519, NULL, g_defEalExchX25519, NULL, \
NULL)
#endif
#ifdef HITLS_CRYPTO_MLDSA
DECODER_DEFINE_DER2KEY_NEW_CTX(Mldsa, CRYPT_PKEY_ML_DSA, g_defEalKeyMgmtMlDsa, NULL, NULL, g_defEalSignMlDsa, NULL)
#endif
#ifdef HITLS_CRYPTO_COMPOSITE
DECODER_DEFINE_DER2KEY_NEW_CTX(Composite, CRYPT_PKEY_COMPOSITE, g_defEalKeyMgmtComposite, \
NULL, NULL, g_defEalSignComposite, NULL)
#endif
#ifdef HITLS_CRYPTO_XMSS
DECODER_DEFINE_DER2KEY_NEW_CTX(Xmss, CRYPT_PKEY_XMSS, g_defEalKeyMgmtXmss, NULL, NULL, \
g_defEalSignXmss, NULL)
#endif
#ifdef HITLS_CRYPTO_XMSSMT
DECODER_DEFINE_DER2KEY_NEW_CTX(Xmssmt, CRYPT_PKEY_XMSSMT, g_defEalKeyMgmtXmssmt, NULL, NULL, \
g_defEalSignXmssmt, NULL)
#endif
#ifdef HITLS_CRYPTO_SLH_DSA
DECODER_DEFINE_DER2KEY_NEW_CTX(SlhDsa, CRYPT_PKEY_SLH_DSA, g_defEalKeyMgmtSlhDsa, NULL, NULL, \
g_defEalSignSlhDsa, NULL)
#endif
#ifdef HITLS_CRYPTO_MLKEM
DECODER_DEFINE_DER2KEY_NEW_CTX(Mlkem, CRYPT_PKEY_ML_KEM, g_defEalKeyMgmtMlKem, NULL, NULL, \
NULL, g_defEalMlKem)
#endif
#ifdef HITLS_CRYPTO_RSA
DECODER_DEFINE_PRVKEY_DER2KEY_DECODE(Rsa, CRYPT_RSA_Ctx, CRYPT_RSA_ParsePrikeyAsn1Buff)
DECODER_DEFINE_PUBKEY_DER2KEY_DECODE(Rsa, CRYPT_RSA_Ctx, CRYPT_RSA_ParsePubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(Rsa, CRYPT_RSA_Ctx, CRYPT_RSA_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(Rsa, CRYPT_RSA_Ctx, CRYPT_RSA_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_PKCS8_DECODE(Rsa, CRYPT_RSA_Ctx, CRYPT_RSA_ParsePkcs8Key)
#endif
#ifdef HITLS_CRYPTO_ECDSA
DECODER_DEFINE_PRVKEY_DER2KEY_DECODE(Ecdsa, void, CRYPT_ECC_ParsePrikeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(Ecdsa, void, CRYPT_ECC_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(Ecdsa, void, CRYPT_ECC_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_PKCS8_DECODE(Ecdsa, void, CRYPT_ECC_ParsePkcs8Key)
#endif
#ifdef HITLS_CRYPTO_SM2
DECODER_DEFINE_PRVKEY_DER2KEY_DECODE(Sm2, CRYPT_SM2_Ctx, CRYPT_SM2_ParsePrikeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(Sm2, CRYPT_SM2_Ctx, CRYPT_SM2_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(Sm2, CRYPT_SM2_Ctx, CRYPT_SM2_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_PKCS8_DECODE(Sm2, CRYPT_SM2_Ctx, CRYPT_SM2_ParsePkcs8Key)
#endif
#ifdef HITLS_CRYPTO_ED25519
DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(Ed25519, CRYPT_CURVE25519_Ctx, CRYPT_ED25519_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(Ed25519, CRYPT_CURVE25519_Ctx, CRYPT_ED25519_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_PKCS8_DECODE(Ed25519, CRYPT_CURVE25519_Ctx, CRYPT_ED25519_ParsePkcs8Key)
#endif
#ifdef HITLS_CRYPTO_X25519
DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(X25519, CRYPT_CURVE25519_Ctx, CRYPT_X25519_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(X25519, CRYPT_CURVE25519_Ctx, CRYPT_X25519_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_PKCS8_DECODE(X25519, CRYPT_CURVE25519_Ctx, CRYPT_X25519_ParsePkcs8Key)
#endif
#ifdef HITLS_CRYPTO_MLDSA
DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(Mldsa, CRYPT_ML_DSA_Ctx, CRYPT_MLDSA_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(Mldsa, CRYPT_ML_DSA_Ctx, CRYPT_MLDSA_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_PKCS8_DECODE(Mldsa, CRYPT_ML_DSA_Ctx, CRYPT_MLDSA_ParsePkcs8key)
#endif
#ifdef HITLS_CRYPTO_COMPOSITE
DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(Composite, CRYPT_CompositeCtx, \
CRYPT_COMPOSITE_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(Composite, CRYPT_CompositeCtx, \
CRYPT_COMPOSITE_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_PKCS8_DECODE(Composite, CRYPT_CompositeCtx, CRYPT_COMPOSITE_ParsePkcs8key)
#endif
#ifdef HITLS_CRYPTO_SLH_DSA
DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(SlhDsa, CryptSlhDsaCtx, CRYPT_SLHDSA_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(SlhDsa, CryptSlhDsaCtx, CRYPT_SLHDSA_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_PKCS8_DECODE(SlhDsa, CryptSlhDsaCtx, CRYPT_SLHDSA_ParsePkcs8key)
#endif
#ifdef HITLS_CRYPTO_MLKEM
DECODER_DEFINE_SUBPUBKEY_DER2KEY_DECODE(Mlkem, CRYPT_ML_KEM_Ctx, CRYPT_MLKEM_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(Mlkem, CRYPT_ML_KEM_Ctx, CRYPT_MLKEM_ParseSubPubkeyAsn1Buff)
DECODER_DEFINE_PKCS8_DECODE(Mlkem, CRYPT_ML_KEM_Ctx, CRYPT_MLKEM_ParsePkcs8key)
#endif
#ifdef HITLS_CRYPTO_XMSS
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(Xmss, CryptXmssCtx, CRYPT_XMSS_ParseSubPubkeyAsn1Buff)
#endif
#ifdef HITLS_CRYPTO_XMSSMT
DECODER_DEFINE_SUBPUBKEY_WITHOUT_SEQ_DER2KEY_DECODE(Xmssmt, CryptXmssCtx, CRYPT_XMSSMT_ParseSubPubkeyAsn1Buff)
#endif
#endif
#endif