* 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"
#ifdef HITLS_CRYPTO_KEY_INFO
#include <stdint.h>
#include <string.h>
#include "bsl_err_internal.h"
#include "bsl_obj_internal.h"
#include "bsl_print.h"
#include "crypt_utils.h"
#include "crypt_eal_pkey.h"
#include "crypt_errno.h"
#include "crypt_codecskey_local.h"
#include "crypt_codecskey.h"
#define CRYPT_UNKOWN_STRING "Unknown\n"
#define CRYPT_UNSUPPORT_ALG "Unsupported alg\n"
#define CRYPT_PUB_KEY_BITS_FMT "Public-Key: (%d bit)\n"
#define CRYPT_PRV_KEY_BITS_FMT "Private-Key: (%d bit)\n"
static int32_t PrintKeyBits(bool isEcc, bool isPrv, uint32_t layer, CRYPT_EAL_PkeyCtx *pkey, BSL_UIO *uio)
{
int32_t ret;
uint32_t bits = 0;
if (isEcc == true) {
ret = CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_ECC_ORDER_BITS, &bits, sizeof(uint32_t));
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
} else {
bits = CRYPT_EAL_PkeyGetKeyBits(pkey);
}
return BSL_PRINT_Fmt(layer, uio, isPrv == true ? CRYPT_PRV_KEY_BITS_FMT : CRYPT_PUB_KEY_BITS_FMT, bits);
}
#if defined(HITLS_CRYPTO_ECDSA) || defined(HITLS_CRYPTO_SM2)
static int32_t PrintEccPubkey(uint32_t layer, CRYPT_EAL_PkeyCtx *pkey, BSL_UIO *uio)
{
RETURN_RET_IF(PrintKeyBits(true, false, layer, pkey, uio) != 0, CRYPT_DECODE_PRINT_KEYBITS);
CRYPT_EAL_PkeyPub pub = {0};
int32_t ret = GetCommonPubKey(pkey, &pub);
if (ret != CRYPT_SUCCESS) {
return ret;
}
(void)BSL_PRINT_Fmt(layer, uio, "Pub:\n");
(void)BSL_PRINT_Hex(layer + 1, false, pub.key.eccPub.data, pub.key.eccPub.len, uio);
BSL_SAL_Free(pub.key.eccPub.data);
CRYPT_PKEY_ParaId paraId =
CRYPT_EAL_PkeyGetId(pkey) == CRYPT_PKEY_SM2 ? CRYPT_ECC_SM2 : CRYPT_EAL_PkeyGetParaId(pkey);
const char *name = BSL_OBJ_GetOidNameFromCID((BslCid)paraId);
(void)BSL_PRINT_Fmt(layer, uio, "ANS1 OID: %s\n", name == NULL ? CRYPT_UNKOWN_STRING : name);
return CRYPT_SUCCESS;
}
#endif
#ifdef HITLS_CRYPTO_RSA
int32_t CRYPT_EAL_PrintRsaPssPara(uint32_t layer, CRYPT_RSA_PssPara *para, BSL_UIO *uio)
{
if (para == NULL || uio == NULL) {
return CRYPT_INVALID_ARG;
}
const char *name = BSL_OBJ_GetOidNameFromCID((BslCid)para->mdId);
(void)BSL_PRINT_Fmt(layer, uio, "Hash Algorithm: %s%s\n",
name == NULL ? CRYPT_UNKOWN_STRING : name, para->mdId == CRYPT_MD_SHA1 ? " (default)" : "");
name = BSL_OBJ_GetOidNameFromCID((BslCid)para->mgfId);
(void)BSL_PRINT_Fmt(layer, uio, "Mask Algorithm: %s%s\n",
name == NULL ? CRYPT_UNKOWN_STRING : name, para->mgfId == CRYPT_MD_SHA1 ? " (default)" : "");
(void)BSL_PRINT_Fmt(layer, uio, "Salt Length: 0x%x%s\n", para->saltLen, para->saltLen == 20 ? " (default)" : "");
return CRYPT_SUCCESS;
}
static int32_t PrintRsaPssPara(uint32_t layer, CRYPT_EAL_PkeyCtx *pkey, BSL_UIO *uio)
{
int32_t padType = 0;
CRYPT_RSA_PssPara para;
int32_t ret = CRYPT_EAL_GetRsaPssPara(pkey, ¶, &padType);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
if (padType != CRYPT_EMSA_PSS) {
return CRYPT_SUCCESS;
}
if (para.saltLen <= 0 && para.mdId == 0 && para.mgfId == 0) {
return BSL_PRINT_Fmt(layer, uio, "No PSS parameter restrictions\n");
}
(void)BSL_PRINT_Fmt(layer, uio, "PSS parameter restrictions:\n");
return CRYPT_EAL_PrintRsaPssPara(layer + 1, ¶, uio);
}
static int32_t PrintRsaPubkey(uint32_t layer, CRYPT_EAL_PkeyCtx *pkey, BSL_UIO *uio)
{
RETURN_RET_IF(PrintKeyBits(false, false, layer, pkey, uio) != 0, CRYPT_DECODE_PRINT_KEYBITS);
CRYPT_EAL_PkeyPub pub;
int32_t ret = GetRsaPubKey(pkey, &pub);
if (ret != CRYPT_SUCCESS) {
return ret;
}
(void)BSL_PRINT_Fmt(layer, uio, "Modulus:\n");
(void)BSL_PRINT_Hex(layer + 1, false, pub.key.rsaPub.n, pub.key.rsaPub.nLen, uio);
(void)BSL_PRINT_Number(layer, "Exponent", pub.key.rsaPub.e, pub.key.rsaPub.eLen, uio);
BSL_SAL_Free(pub.key.rsaPub.n);
return PrintRsaPssPara(layer, pkey, uio);
}
#endif
int32_t CRYPT_EAL_PrintPubkey(uint32_t layer, CRYPT_EAL_PkeyCtx *pkey, BSL_UIO *uio)
{
if (uio == NULL) {
return CRYPT_INVALID_ARG;
}
CRYPT_PKEY_AlgId algId = CRYPT_EAL_PkeyGetId(pkey);
switch (algId) {
#ifdef HITLS_CRYPTO_RSA
case CRYPT_PKEY_RSA:
return PrintRsaPubkey(layer, pkey, uio);
#endif
#if defined(HITLS_CRYPTO_ECDSA) || defined(HITLS_CRYPTO_SM2)
case CRYPT_PKEY_ECDSA:
case CRYPT_PKEY_SM2:
return PrintEccPubkey(layer, pkey, uio);
#endif
default:
return CRYPT_DECODE_PRINT_UNSUPPORT_ALG;
}
}
#ifdef HITLS_CRYPTO_RSA
static int32_t PrintRsaPrikey(uint32_t layer, CRYPT_EAL_PkeyCtx *pkey, BSL_UIO *uio)
{
RETURN_RET_IF(PrintKeyBits(false, true, layer, pkey, uio) != 0, CRYPT_DECODE_PRINT_KEYBITS);
CRYPT_EAL_PkeyPrv pri = {0};
int32_t ret = CRYPT_EAL_InitRsaPrv(pkey, &pri);
if (ret != CRYPT_SUCCESS) {
return ret;
}
ret = CRYPT_EAL_PkeyGetPrv(pkey, &pri);
if (ret != CRYPT_SUCCESS) {
CRYPT_EAL_DeinitRsaPrv(&pri);
return ret;
}
(void)BSL_PRINT_Fmt(layer, uio, "Modulus:\n");
if (BSL_PRINT_Hex(layer + 1, false, pri.key.rsaPrv.n, pri.key.rsaPrv.nLen, uio) != 0) {
CRYPT_EAL_DeinitRsaPrv(&pri);
BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PRINT_MODULUS);
return CRYPT_DECODE_PRINT_MODULUS;
}
if (BSL_PRINT_Number(layer, "PublicExponent", pri.key.rsaPrv.e, pri.key.rsaPrv.eLen, uio) != 0) {
CRYPT_EAL_DeinitRsaPrv(&pri);
BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PRINT_EXPONENT);
return CRYPT_DECODE_PRINT_EXPONENT;
}
(void)BSL_PRINT_Fmt(layer, uio, "PrivateExponent:\n");
if (BSL_PRINT_Hex(layer + 1, false, pri.key.rsaPrv.d, pri.key.rsaPrv.dLen, uio) != 0) {
CRYPT_EAL_DeinitRsaPrv(&pri);
BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PRINT_MODULUS);
return CRYPT_DECODE_PRINT_MODULUS;
}
(void)BSL_PRINT_Fmt(layer, uio, "Prime1:\n");
if (BSL_PRINT_Hex(layer + 1, false, pri.key.rsaPrv.p, pri.key.rsaPrv.pLen, uio) != 0) {
CRYPT_EAL_DeinitRsaPrv(&pri);
BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PRINT_MODULUS);
return CRYPT_DECODE_PRINT_MODULUS;
}
(void)BSL_PRINT_Fmt(layer, uio, "Prime2:\n");
if (BSL_PRINT_Hex(layer + 1, false, pri.key.rsaPrv.q, pri.key.rsaPrv.qLen, uio) != 0) {
CRYPT_EAL_DeinitRsaPrv(&pri);
BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PRINT_MODULUS);
return CRYPT_DECODE_PRINT_MODULUS;
}
(void)BSL_PRINT_Fmt(layer, uio, "Exponent1:\n");
if (BSL_PRINT_Hex(layer + 1, false, pri.key.rsaPrv.dP, pri.key.rsaPrv.dPLen, uio) != 0) {
CRYPT_EAL_DeinitRsaPrv(&pri);
BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PRINT_MODULUS);
return CRYPT_DECODE_PRINT_MODULUS;
}
(void)BSL_PRINT_Fmt(layer, uio, "Exponent2:\n");
if (BSL_PRINT_Hex(layer + 1, false, pri.key.rsaPrv.dQ, pri.key.rsaPrv.dQLen, uio) != 0) {
CRYPT_EAL_DeinitRsaPrv(&pri);
BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PRINT_MODULUS);
return CRYPT_DECODE_PRINT_MODULUS;
}
(void)BSL_PRINT_Fmt(layer, uio, "Coefficient:\n");
if (BSL_PRINT_Hex(layer + 1, false, pri.key.rsaPrv.qInv, pri.key.rsaPrv.qInvLen, uio) != 0) {
CRYPT_EAL_DeinitRsaPrv(&pri);
BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PRINT_MODULUS);
return CRYPT_DECODE_PRINT_MODULUS;
}
CRYPT_EAL_DeinitRsaPrv(&pri);
return CRYPT_SUCCESS;
}
#endif
int32_t CRYPT_EAL_PrintPrikey(uint32_t layer, CRYPT_EAL_PkeyCtx *pkey, BSL_UIO *uio)
{
if (uio == NULL) {
return CRYPT_INVALID_ARG;
}
CRYPT_PKEY_AlgId algId = CRYPT_EAL_PkeyGetId(pkey);
switch (algId) {
#ifdef HITLS_CRYPTO_RSA
case CRYPT_PKEY_RSA:
return PrintRsaPrikey(layer, pkey, uio);
#endif
default:
return CRYPT_DECODE_PRINT_UNSUPPORT_ALG;
}
}
#endif