* 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_MD5) || defined(HITLS_CRYPTO_SHA1) || defined(HITLS_CRYPTO_SHA224) || \
defined(HITLS_CRYPTO_SHA256) || defined(HITLS_CRYPTO_SHA384) || defined(HITLS_CRYPTO_SHA512) || \
defined(HITLS_CRYPTO_SHA3) || defined(HITLS_CRYPTO_SM3)) && defined(HITLS_CRYPTO_PROVIDER)
#include "crypt_eal_implprovider.h"
#include "crypt_md5.h"
#include "crypt_sha1.h"
#include "crypt_sha2.h"
#include "crypt_sha3.h"
#include "crypt_sm3.h"
#include "bsl_sal.h"
#include "crypt_errno.h"
#include "bsl_log_internal.h"
#include "bsl_err_internal.h"
#include "crypt_ealinit.h"
#include "crypt_default_provider.h"
static void *CRYPT_EAL_DefMdNewCtx(CRYPT_EAL_DefProvCtx *provCtx, int32_t algId)
{
void *libCtx = provCtx == NULL ? NULL : provCtx->libCtx;
#ifdef HITLS_CRYPTO_ASM_CHECK
if (CRYPT_ASMCAP_Md(algId) != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT);
return NULL;
}
#endif
switch (algId) {
#ifdef HITLS_CRYPTO_MD5
case CRYPT_MD_MD5:
return CRYPT_MD5_NewCtxEx(libCtx, algId);
#endif
#ifdef HITLS_CRYPTO_SHA1
case CRYPT_MD_SHA1:
return CRYPT_SHA1_NewCtxEx(libCtx, algId);
#endif
#ifdef HITLS_CRYPTO_SHA224
case CRYPT_MD_SHA224:
return CRYPT_SHA2_224_NewCtxEx(libCtx, algId);
#endif
#ifdef HITLS_CRYPTO_SHA256
case CRYPT_MD_SHA256:
return CRYPT_SHA2_256_NewCtxEx(libCtx, algId);
#endif
#ifdef HITLS_CRYPTO_SHA384
case CRYPT_MD_SHA384:
return CRYPT_SHA2_384_NewCtxEx(libCtx, algId);
#endif
#ifdef HITLS_CRYPTO_SHA512
case CRYPT_MD_SHA512:
return CRYPT_SHA2_512_NewCtxEx(libCtx, algId);
#endif
#ifdef HITLS_CRYPTO_SHA3
case CRYPT_MD_SHA3_224:
case CRYPT_MD_SHA3_256:
case CRYPT_MD_SHA3_384:
case CRYPT_MD_SHA3_512:
return CRYPT_SHA3_256_NewCtxEx(libCtx, algId);
case CRYPT_MD_SHAKE128:
case CRYPT_MD_SHAKE256:
return CRYPT_SHAKE256_NewCtxEx(libCtx, algId);
#endif
#ifdef HITLS_CRYPTO_SM3
case CRYPT_MD_SM3:
return CRYPT_SM3_NewCtxEx(libCtx, algId);
#endif
default:
BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_NOT_SUPPORT);
return NULL;
}
}
#ifdef HITLS_CRYPTO_MD5
const CRYPT_EAL_Func g_defEalMdMd5[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_MD5_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_MD5_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_MD5_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_MD5_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_MD5_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_MD5_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_MD5_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_MD5_GetParam},
CRYPT_EAL_FUNC_END,
};
#endif
#ifdef HITLS_CRYPTO_SHA1
const CRYPT_EAL_Func g_defEalMdSha1[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHA1_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHA1_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHA1_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHA1_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHA1_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHA1_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHA1_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHA1_GetParam},
CRYPT_EAL_FUNC_END,
};
#endif
#ifdef HITLS_CRYPTO_SHA224
const CRYPT_EAL_Func g_defEalMdSha224[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHA2_224_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHA2_224_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHA2_224_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHA2_224_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHA2_224_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHA2_224_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHA2_224_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHA2_224_GetParam},
CRYPT_EAL_FUNC_END,
};
#endif
#ifdef HITLS_CRYPTO_SHA256
const CRYPT_EAL_Func g_defEalMdSha256[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHA2_256_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHA2_256_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHA2_256_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHA2_256_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHA2_256_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHA2_256_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHA2_256_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHA2_256_GetParam},
CRYPT_EAL_FUNC_END,
};
#endif
#ifdef HITLS_CRYPTO_SHA384
const CRYPT_EAL_Func g_defEalMdSha384[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHA2_384_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHA2_384_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHA2_384_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHA2_384_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHA2_384_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHA2_384_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHA2_384_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHA2_384_GetParam},
CRYPT_EAL_FUNC_END,
};
#endif
#ifdef HITLS_CRYPTO_SHA512
const CRYPT_EAL_Func g_defEalMdSha512[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHA2_512_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHA2_512_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHA2_512_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHA2_512_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHA2_512_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHA2_512_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHA2_512_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHA2_512_GetParam},
CRYPT_EAL_FUNC_END,
};
#endif
#ifdef HITLS_CRYPTO_SHA3
const CRYPT_EAL_Func g_defEalMdSha3224[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHA3_224_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHA3_224_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHA3_224_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHA3_224_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHA3_224_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHA3_224_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHA3_224_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHA3_224_GetParam},
CRYPT_EAL_FUNC_END,
};
const CRYPT_EAL_Func g_defEalMdSha3256[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHA3_256_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHA3_256_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHA3_256_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHA3_256_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHA3_256_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHA3_256_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHA3_256_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHA3_256_GetParam},
CRYPT_EAL_FUNC_END,
};
const CRYPT_EAL_Func g_defEalMdSha3384[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHA3_384_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHA3_384_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHA3_384_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHA3_384_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHA3_384_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHA3_384_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHA3_384_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHA3_384_GetParam},
CRYPT_EAL_FUNC_END,
};
const CRYPT_EAL_Func g_defEalMdSha3512[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHA3_512_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHA3_512_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHA3_512_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHA3_512_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHA3_512_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHA3_512_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHA3_512_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHA3_512_GetParam},
CRYPT_EAL_FUNC_END,
};
const CRYPT_EAL_Func g_defEalMdShake128[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHAKE128_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHAKE128_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHAKE128_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHAKE128_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHAKE128_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHAKE128_FreeCtx},
{CRYPT_EAL_IMPLMD_SQUEEZE, (CRYPT_EAL_ImplMdSqueeze)CRYPT_SHAKE128_Squeeze},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHAKE128_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHAKE128_GetParam},
CRYPT_EAL_FUNC_END,
};
const CRYPT_EAL_Func g_defEalMdShake256[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SHAKE256_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SHAKE256_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SHAKE256_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SHAKE256_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SHAKE256_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SHAKE256_FreeCtx},
{CRYPT_EAL_IMPLMD_SQUEEZE, (CRYPT_EAL_ImplMdSqueeze)CRYPT_SHAKE256_Squeeze},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SHAKE256_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SHAKE256_GetParam},
CRYPT_EAL_FUNC_END,
};
#endif
#ifdef HITLS_CRYPTO_SM3
const CRYPT_EAL_Func g_defEalMdSm3[] = {
{CRYPT_EAL_IMPLMD_NEWCTX, (CRYPT_EAL_ImplMdNewCtx)CRYPT_EAL_DefMdNewCtx},
{CRYPT_EAL_IMPLMD_INITCTX, (CRYPT_EAL_ImplMdInitCtx)CRYPT_SM3_InitEx},
{CRYPT_EAL_IMPLMD_UPDATE, (CRYPT_EAL_ImplMdUpdate)CRYPT_SM3_Update},
{CRYPT_EAL_IMPLMD_FINAL, (CRYPT_EAL_ImplMdFinal)CRYPT_SM3_Final},
{CRYPT_EAL_IMPLMD_DEINITCTX, (CRYPT_EAL_ImplMdDeInitCtx)CRYPT_SM3_Deinit},
{CRYPT_EAL_IMPLMD_DUPCTX, (CRYPT_EAL_ImplMdDupCtx)CRYPT_SM3_DupCtx},
{CRYPT_EAL_IMPLMD_FREECTX, (CRYPT_EAL_ImplMdFreeCtx)CRYPT_SM3_FreeCtx},
{CRYPT_EAL_IMPLMD_COPYCTX, (CRYPT_EAL_ImplMdCopyCtx)CRYPT_SM3_CopyCtx},
{CRYPT_EAL_IMPLMD_GETPARAM, (CRYPT_EAL_ImplMdGetParam)CRYPT_SM3_GetParam},
CRYPT_EAL_FUNC_END,
};
#endif
#endif