mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
Support RSA and ECC in wolfSSL_DigestSign/Verify*
This commit is contained in:
49
src/ssl.c
49
src/ssl.c
@@ -6657,6 +6657,21 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out, unsigned char** in,
|
||||
if (out != NULL) {
|
||||
*out = pkey;
|
||||
}
|
||||
|
||||
pkey->ownEcc = 1;
|
||||
pkey->ecc = wolfSSL_EC_KEY_new();
|
||||
if (pkey->ecc == NULL) {
|
||||
wolfSSL_EVP_PKEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wolfSSL_EC_KEY_LoadDer_ex(pkey->ecc,
|
||||
(const unsigned char*)pkey->pkey.ptr,
|
||||
pkey->pkey_sz, WOLFSSL_EC_KEY_LOAD_PUBLIC) != 1) {
|
||||
wolfSSL_EVP_PKEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pkey;
|
||||
}
|
||||
}
|
||||
@@ -12769,6 +12784,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
||||
if ((out == NULL) || (in == NULL)) return WOLFSSL_FAILURE;
|
||||
WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_copy_ex");
|
||||
XMEMCPY(out, in, sizeof(WOLFSSL_EVP_MD_CTX));
|
||||
if (in->pctx != NULL) {
|
||||
out->pctx = wolfSSL_EVP_PKEY_CTX_new(in->pctx->pkey, NULL);
|
||||
if (out->pctx == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -12952,6 +12972,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
||||
int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx)
|
||||
{
|
||||
WOLFSSL_ENTER("EVP_MD_CTX_cleanup");
|
||||
if (ctx->pctx != NULL)
|
||||
wolfSSL_EVP_PKEY_CTX_free(ctx->pctx);
|
||||
ForceZero(ctx, sizeof(*ctx));
|
||||
ctx->macType = 0xFF;
|
||||
return 1;
|
||||
@@ -28518,8 +28540,15 @@ int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
/* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
|
||||
int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key,
|
||||
const unsigned char* derBuf, int derSz)
|
||||
int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
|
||||
int derSz)
|
||||
{
|
||||
return wolfSSL_EC_KEY_LoadDer_ex(key, derBuf, derSz,
|
||||
WOLFSSL_EC_KEY_LOAD_PRIVATE);
|
||||
}
|
||||
|
||||
int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
|
||||
int derSz, int opt)
|
||||
{
|
||||
word32 idx = 0;
|
||||
int ret;
|
||||
@@ -28531,9 +28560,21 @@ int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key,
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal, derSz);
|
||||
if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
|
||||
ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
|
||||
derSz);
|
||||
}
|
||||
else {
|
||||
ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
|
||||
derSz);
|
||||
}
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
|
||||
if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
|
||||
WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
|
||||
}
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
|
144
tests/api.c
144
tests/api.c
@@ -16796,6 +16796,148 @@ static void test_wolfSSL_EVP_MD_hmac_signing(void)
|
||||
}
|
||||
|
||||
|
||||
static void test_wolfSSL_EVP_MD_rsa_signing(void)
|
||||
{
|
||||
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048)
|
||||
WOLFSSL_EVP_PKEY* privKey;
|
||||
WOLFSSL_EVP_PKEY* pubKey;
|
||||
const char testData[] = "Hi There";
|
||||
WOLFSSL_EVP_MD_CTX mdCtx;
|
||||
size_t checkSz = -1;
|
||||
int sz = 2048 / 8;
|
||||
const unsigned char* cp;
|
||||
unsigned char* p;
|
||||
unsigned char check[2048/8];
|
||||
|
||||
printf(testingFmt, "wolfSSL_EVP_MD_rsa_signing()");
|
||||
|
||||
cp = client_key_der_2048;
|
||||
AssertNotNull((privKey = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, &cp,
|
||||
sizeof_client_key_der_2048)));
|
||||
p = (unsigned char *)client_keypub_der_2048;
|
||||
AssertNotNull((pubKey = wolfSSL_d2i_PUBKEY(NULL, &p,
|
||||
sizeof_client_keypub_der_2048)));
|
||||
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
|
||||
NULL, privKey), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData,
|
||||
(unsigned int)XSTRLEN(testData)), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
|
||||
AssertIntEQ((int)checkSz, sz);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
|
||||
AssertIntEQ((int)checkSz,sz);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
|
||||
NULL, pubKey), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData,
|
||||
(unsigned int)XSTRLEN(testData)),
|
||||
1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
|
||||
NULL, privKey), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData, 4), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
|
||||
AssertIntEQ((int)checkSz, sz);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
|
||||
AssertIntEQ((int)checkSz, sz);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData + 4,
|
||||
(unsigned int)XSTRLEN(testData) - 4), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
|
||||
AssertIntEQ((int)checkSz, sz);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
|
||||
NULL, pubKey), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, 4), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData + 4,
|
||||
(unsigned int)XSTRLEN(testData) - 4),
|
||||
1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
|
||||
wolfSSL_EVP_PKEY_free(pubKey);
|
||||
wolfSSL_EVP_PKEY_free(privKey);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
}
|
||||
|
||||
|
||||
static void test_wolfSSL_EVP_MD_ecc_signing(void)
|
||||
{
|
||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
|
||||
WOLFSSL_EVP_PKEY* privKey;
|
||||
WOLFSSL_EVP_PKEY* pubKey;
|
||||
const char testData[] = "Hi There";
|
||||
WOLFSSL_EVP_MD_CTX mdCtx;
|
||||
size_t checkSz = -1;
|
||||
const unsigned char* cp;
|
||||
unsigned char* p;
|
||||
unsigned char check[2048/8];
|
||||
|
||||
printf(testingFmt, "wolfSSL_EVP_MD_ecc_signing()");
|
||||
|
||||
cp = ecc_clikey_der_256;
|
||||
AssertNotNull((privKey = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL, &cp,
|
||||
sizeof_ecc_clikey_der_256)));
|
||||
p = (unsigned char *)ecc_clikeypub_der_256;
|
||||
AssertNotNull((pubKey = wolfSSL_d2i_PUBKEY(NULL, &p,
|
||||
sizeof_ecc_clikeypub_der_256)));
|
||||
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
|
||||
NULL, privKey), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData,
|
||||
(unsigned int)XSTRLEN(testData)), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
|
||||
NULL, pubKey), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData,
|
||||
(unsigned int)XSTRLEN(testData)),
|
||||
1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
|
||||
NULL, privKey), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData, 4), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData + 4,
|
||||
(unsigned int)XSTRLEN(testData) - 4), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
|
||||
NULL, pubKey), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, 4), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData + 4,
|
||||
(unsigned int)XSTRLEN(testData) - 4),
|
||||
1);
|
||||
AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
|
||||
wolfSSL_EVP_PKEY_free(pubKey);
|
||||
wolfSSL_EVP_PKEY_free(privKey);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
}
|
||||
|
||||
|
||||
static void test_wolfSSL_CTX_add_extra_chain_cert(void)
|
||||
{
|
||||
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
|
||||
@@ -20957,6 +21099,8 @@ void ApiTest(void)
|
||||
test_wolfSSL_ctrl();
|
||||
test_wolfSSL_EVP_PKEY_new_mac_key();
|
||||
test_wolfSSL_EVP_MD_hmac_signing();
|
||||
test_wolfSSL_EVP_MD_rsa_signing();
|
||||
test_wolfSSL_EVP_MD_ecc_signing();
|
||||
test_wolfSSL_CTX_add_extra_chain_cert();
|
||||
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
test_wolfSSL_ERR_peek_last_error_line();
|
||||
|
@@ -12895,7 +12895,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
|
||||
}
|
||||
|
||||
/* key header */
|
||||
ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
|
||||
ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -12905,6 +12905,8 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
|
||||
return ASN_ECC_KEY_E;
|
||||
}
|
||||
|
||||
*inOutIdx += length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1124,110 +1124,137 @@ const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey,
|
||||
return (const unsigned char*)pkey->pkey.ptr;
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_EVP_DigestSignInit(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
WOLFSSL_EVP_PKEY_CTX **pctx,
|
||||
const WOLFSSL_EVP_MD *type,
|
||||
WOLFSSL_ENGINE *e,
|
||||
WOLFSSL_EVP_PKEY *pkey)
|
||||
/* Initialize an EVP_DigestSign/Verify operation.
|
||||
* Initialize a digest for RSA and ECC keys, or HMAC for HMAC key.
|
||||
*/
|
||||
static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
WOLFSSL_EVP_PKEY_CTX **pctx,
|
||||
const WOLFSSL_EVP_MD *type,
|
||||
WOLFSSL_ENGINE *e,
|
||||
WOLFSSL_EVP_PKEY *pkey)
|
||||
{
|
||||
int hashType;
|
||||
const unsigned char* key;
|
||||
size_t keySz;
|
||||
if (pkey->type == EVP_PKEY_HMAC) {
|
||||
int hashType;
|
||||
const unsigned char* key;
|
||||
size_t keySz;
|
||||
|
||||
/* Unused parameters */
|
||||
(void)pctx;
|
||||
(void)e;
|
||||
if (XSTRNCMP(type, "SHA256", 6) == 0) {
|
||||
hashType = WC_SHA256;
|
||||
}
|
||||
#ifdef WOLFSSL_SHA224
|
||||
else if (XSTRNCMP(type, "SHA224", 6) == 0) {
|
||||
hashType = WC_SHA224;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
else if (XSTRNCMP(type, "SHA384", 6) == 0) {
|
||||
hashType = WC_SHA384;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
else if (XSTRNCMP(type, "SHA512", 6) == 0) {
|
||||
hashType = WC_SHA512;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
else if (XSTRNCMP(type, "MD5", 3) == 0) {
|
||||
hashType = WC_MD5;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
/* has to be last since would pick or 224, 256, 384, or 512 too */
|
||||
else if (XSTRNCMP(type, "SHA", 3) == 0) {
|
||||
hashType = WC_SHA;
|
||||
}
|
||||
#endif /* NO_SHA */
|
||||
else
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
WOLFSSL_ENTER("EVP_DigestSignInit");
|
||||
key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz);
|
||||
|
||||
if (ctx == NULL || type == NULL || pkey == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* compile-time validation of ASYNC_CTX_SIZE */
|
||||
typedef char async_test[WC_ASYNC_DEV_SIZE >= sizeof(WC_ASYNC_DEV) ?
|
||||
1 : -1];
|
||||
(void)sizeof(async_test);
|
||||
#endif
|
||||
if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (XSTRNCMP(type, "SHA256", 6) == 0) {
|
||||
hashType = WC_SHA256;
|
||||
ctx->macType = NID_hmac & 0xFF;
|
||||
}
|
||||
#ifdef WOLFSSL_SHA224
|
||||
else if (XSTRNCMP(type, "SHA224", 6) == 0) {
|
||||
hashType = WC_SHA224;
|
||||
else {
|
||||
int ret;
|
||||
|
||||
if (ctx->pctx == NULL)
|
||||
ctx->pctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e);
|
||||
if (ctx->pctx == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
ret = wolfSSL_EVP_DigestInit(ctx, type);
|
||||
if (ret == WOLFSSL_SUCCESS && pctx != NULL)
|
||||
*pctx = ctx->pctx;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
else if (XSTRNCMP(type, "SHA384", 6) == 0) {
|
||||
hashType = WC_SHA384;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Update an EVP_DigestSign/Verify operation.
|
||||
* Update a digest for RSA and ECC keys, or HMAC for HMAC key.
|
||||
*/
|
||||
static int wolfssl_evp_digest_pk_update(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
const void *d, unsigned int cnt)
|
||||
{
|
||||
if (ctx->pctx == NULL) {
|
||||
if (ctx->macType != (NID_hmac & 0xFF))
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, cnt) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
else if (XSTRNCMP(type, "SHA512", 6) == 0) {
|
||||
hashType = WC_SHA512;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
else if (XSTRNCMP(type, "MD5", 3) == 0) {
|
||||
hashType = WC_MD5;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
/* has to be last since would pick or 224, 256, 384, or 512 too */
|
||||
else if (XSTRNCMP(type, "SHA", 3) == 0) {
|
||||
hashType = WC_SHA;
|
||||
}
|
||||
#endif /* NO_SHA */
|
||||
else
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz);
|
||||
|
||||
if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
ctx->macType = NID_hmac & 0xFF;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
return wolfSSL_EVP_DigestUpdate(ctx, d, cnt);
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
const void *d, unsigned int cnt)
|
||||
/* Finalize an EVP_DigestSign/Verify operation - common part only.
|
||||
* Finalize a digest for RSA and ECC keys, or HMAC for HMAC key.
|
||||
* Copies the digest so that you can keep updating.
|
||||
*/
|
||||
static int wolfssl_evp_digest_pk_final(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
unsigned char *md, unsigned int* mdlen)
|
||||
{
|
||||
WOLFSSL_ENTER("EVP_DigestSignFinal");
|
||||
int ret;
|
||||
|
||||
if (ctx->macType != (NID_hmac & 0xFF))
|
||||
return WOLFSSL_FAILURE;
|
||||
if (ctx->pctx == NULL) {
|
||||
Hmac hmacCopy;
|
||||
|
||||
if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, cnt) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
if (ctx->macType != (NID_hmac & 0xFF))
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
XMEMCPY(&hmacCopy, &ctx->hash.hmac, sizeof(hmacCopy));
|
||||
ret = wc_HmacFinal(&hmacCopy, md) == 0;
|
||||
|
||||
ForceZero(&hmacCopy, sizeof(hmacCopy));
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_EVP_MD_CTX ctxCopy;
|
||||
|
||||
if (wolfSSL_EVP_MD_CTX_copy_ex(&ctxCopy, ctx) != WOLFSSL_SUCCESS)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
ret = wolfSSL_EVP_DigestFinal(&ctxCopy, md, mdlen);
|
||||
wolfSSL_EVP_MD_CTX_cleanup(&ctxCopy);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
unsigned char *sig, size_t *siglen)
|
||||
/* Get the length of the mac based on the digest algorithm. */
|
||||
static int wolfssl_mac_len(unsigned char macType)
|
||||
{
|
||||
unsigned char digest[WC_MAX_DIGEST_SIZE];
|
||||
Hmac hmacCopy;
|
||||
int hashLen, ret;
|
||||
int hashLen;
|
||||
|
||||
WOLFSSL_ENTER("EVP_DigestSignFinal");
|
||||
|
||||
if (ctx == NULL || siglen == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (ctx->macType != (NID_hmac & 0xFF))
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
switch (ctx->hash.hmac.macType) {
|
||||
switch (macType) {
|
||||
#ifndef NO_MD5
|
||||
case WC_MD5:
|
||||
hashLen = WC_MD5_DIGEST_SIZE;
|
||||
@@ -1252,12 +1279,12 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
break;
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_SHA384:
|
||||
hashLen = WC_SHA384_DIGEST_SIZE;
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_SHA512:
|
||||
hashLen = WC_SHA512_DIGEST_SIZE;
|
||||
break;
|
||||
@@ -1270,23 +1297,127 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
#endif /* HAVE_BLAKE2 */
|
||||
|
||||
default:
|
||||
return 0;
|
||||
hashLen = 0;
|
||||
}
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = hashLen;
|
||||
return WOLFSSL_SUCCESS;
|
||||
return hashLen;
|
||||
}
|
||||
|
||||
int wolfSSL_EVP_DigestSignInit(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
WOLFSSL_EVP_PKEY_CTX **pctx,
|
||||
const WOLFSSL_EVP_MD *type,
|
||||
WOLFSSL_ENGINE *e,
|
||||
WOLFSSL_EVP_PKEY *pkey)
|
||||
{
|
||||
WOLFSSL_ENTER("EVP_DigestSignInit");
|
||||
|
||||
if (ctx == NULL || type == NULL || pkey == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey);
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d,
|
||||
unsigned int cnt)
|
||||
{
|
||||
WOLFSSL_ENTER("EVP_DigestSignUpdate");
|
||||
|
||||
if (ctx == NULL || d == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
return wolfssl_evp_digest_pk_update(ctx, d, cnt);
|
||||
}
|
||||
|
||||
int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen)
|
||||
{
|
||||
unsigned char digest[WC_MAX_DIGEST_SIZE];
|
||||
unsigned int hashLen;
|
||||
int ret = WOLFSSL_FAILURE;
|
||||
|
||||
WOLFSSL_ENTER("EVP_DigestSignFinal");
|
||||
|
||||
if (ctx == NULL || siglen == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
/* Return the maximum size of the signaure when sig is NULL. */
|
||||
if (ctx->pctx == NULL) {
|
||||
if (ctx->macType != (NID_hmac & 0xFF))
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = hashLen;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||
else if (ctx->pctx->pkey->type == EVP_PKEY_RSA) {
|
||||
if (sig == NULL) {
|
||||
*siglen = wolfSSL_RSA_size(ctx->pctx->pkey->rsa);
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
else if (ctx->pctx->pkey->type == EVP_PKEY_EC) {
|
||||
if (sig == NULL) {
|
||||
/* SEQ + INT + INT */
|
||||
*siglen = ecc_sets[ctx->pctx->pkey->ecc->group->curve_idx].size * 2
|
||||
+ 8;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((int)(*siglen) > hashLen)
|
||||
*siglen = hashLen;
|
||||
if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (ctx->pctx == NULL) {
|
||||
/* Copy the HMAC result as signature. */
|
||||
if ((unsigned int)(*siglen) > hashLen)
|
||||
*siglen = hashLen;
|
||||
/* May be a truncated signature. */
|
||||
|
||||
XMEMCPY(&hmacCopy, &ctx->hash.hmac, sizeof(hmacCopy));
|
||||
ret = wc_HmacFinal(&hmacCopy, digest) == 0;
|
||||
if (ret == 1)
|
||||
XMEMCPY(sig, digest, *siglen);
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
/* Sign the digest. */
|
||||
switch (ctx->pctx->pkey->type) {
|
||||
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||
case EVP_PKEY_RSA: {
|
||||
unsigned int sigSz;
|
||||
int nid = md2nid(ctx->macType);
|
||||
if (nid < 0) break;
|
||||
ret = wolfSSL_RSA_sign(nid, digest, hashLen, sig, &sigSz,
|
||||
ctx->pctx->pkey->rsa);
|
||||
if (ret >= 0)
|
||||
*siglen = sigSz;
|
||||
break;
|
||||
}
|
||||
#endif /* NO_RSA */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
case EVP_PKEY_EC: {
|
||||
WOLFSSL_ECDSA_SIG *ecdsaSig;
|
||||
ecdsaSig = wolfSSL_ECDSA_do_sign(digest, hashLen,
|
||||
ctx->pctx->pkey->ecc);
|
||||
if (ecdsaSig == NULL)
|
||||
break;
|
||||
*siglen = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig);
|
||||
wolfSSL_ECDSA_SIG_free(ecdsaSig);
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ForceZero(&hmacCopy, sizeof(hmacCopy));
|
||||
ForceZero(digest, sizeof(digest));
|
||||
return ret;
|
||||
}
|
||||
@@ -1297,84 +1428,24 @@ int wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
WOLFSSL_ENGINE *e,
|
||||
WOLFSSL_EVP_PKEY *pkey)
|
||||
{
|
||||
int hashType;
|
||||
const unsigned char* key;
|
||||
size_t keySz;
|
||||
|
||||
/* Unused parameters */
|
||||
(void)pctx;
|
||||
(void)e;
|
||||
|
||||
WOLFSSL_ENTER("EVP_DigestVerifyInit");
|
||||
|
||||
if (ctx == NULL || type == NULL || pkey == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* compile-time validation of ASYNC_CTX_SIZE */
|
||||
typedef char async_test[WC_ASYNC_DEV_SIZE >= sizeof(WC_ASYNC_DEV) ?
|
||||
1 : -1];
|
||||
(void)sizeof(async_test);
|
||||
#endif
|
||||
|
||||
if (XSTRNCMP(type, "SHA256", 6) == 0) {
|
||||
hashType = WC_SHA256;
|
||||
}
|
||||
#ifdef WOLFSSL_SHA224
|
||||
else if (XSTRNCMP(type, "SHA224", 6) == 0) {
|
||||
hashType = WC_SHA224;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
else if (XSTRNCMP(type, "SHA384", 6) == 0) {
|
||||
hashType = WC_SHA384;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
else if (XSTRNCMP(type, "SHA512", 6) == 0) {
|
||||
hashType = WC_SHA512;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
else if (XSTRNCMP(type, "MD5", 3) == 0) {
|
||||
hashType = WC_MD5;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
/* has to be last since would pick or 224, 256, 384, or 512 too */
|
||||
else if (XSTRNCMP(type, "SHA", 3) == 0) {
|
||||
hashType = WC_SHA;
|
||||
}
|
||||
#endif /* NO_SHA */
|
||||
else
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz);
|
||||
|
||||
if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
ctx->macType = NID_hmac & 0xFF;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey);
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
const void *d, size_t cnt)
|
||||
int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d,
|
||||
size_t cnt)
|
||||
{
|
||||
WOLFSSL_ENTER("EVP_DigestVerifyUpdate");
|
||||
|
||||
if (ctx->macType != (NID_hmac & 0xFF))
|
||||
return WOLFSSL_FAILURE;
|
||||
if (ctx == NULL || d == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, (word32)cnt) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
return wolfssl_evp_digest_pk_update(ctx, d, (unsigned int)cnt);
|
||||
}
|
||||
|
||||
|
||||
@@ -1382,79 +1453,66 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,
|
||||
const unsigned char *sig, size_t siglen)
|
||||
{
|
||||
unsigned char digest[WC_MAX_DIGEST_SIZE];
|
||||
Hmac hmacCopy;
|
||||
size_t hashLen;
|
||||
int ret;
|
||||
unsigned int hashLen;
|
||||
|
||||
WOLFSSL_ENTER("EVP_DigestVerifyFinal");
|
||||
|
||||
if (ctx == NULL || sig == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (ctx->macType != (NID_hmac & 0xFF))
|
||||
return WOLFSSL_FAILURE;
|
||||
if (ctx->pctx == NULL) {
|
||||
if (ctx->macType != (NID_hmac & 0xFF))
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
switch (ctx->hash.hmac.macType) {
|
||||
#ifndef NO_MD5
|
||||
case WC_MD5:
|
||||
hashLen = WC_MD5_DIGEST_SIZE;
|
||||
break;
|
||||
#endif /* !NO_MD5 */
|
||||
hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);
|
||||
|
||||
#ifndef NO_SHA
|
||||
case WC_SHA:
|
||||
hashLen = WC_SHA_DIGEST_SIZE;
|
||||
break;
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case WC_SHA224:
|
||||
hashLen = WC_SHA224_DIGEST_SIZE;
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA224 */
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case WC_SHA256:
|
||||
hashLen = WC_SHA256_DIGEST_SIZE;
|
||||
break;
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_SHA384:
|
||||
hashLen = WC_SHA384_DIGEST_SIZE;
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
case WC_SHA512:
|
||||
hashLen = WC_SHA512_DIGEST_SIZE;
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
|
||||
#ifdef HAVE_BLAKE2
|
||||
case BLAKE2B_ID:
|
||||
hashLen = BLAKE2B_OUTBYTES;
|
||||
break;
|
||||
#endif /* HAVE_BLAKE2 */
|
||||
|
||||
default:
|
||||
return 0;
|
||||
if (siglen > hashLen)
|
||||
return WOLFSSL_FAILURE;
|
||||
/* May be a truncated signature. */
|
||||
}
|
||||
|
||||
if (siglen != hashLen)
|
||||
if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
XMEMCPY(&hmacCopy, &ctx->hash.hmac, sizeof(hmacCopy));
|
||||
ret = wc_HmacFinal(&hmacCopy, digest) == 0;
|
||||
if (ret == 1) {
|
||||
if (ctx->pctx == NULL) {
|
||||
/* Check HMAC result matches the signature. */
|
||||
if (XMEMCMP(sig, digest, siglen) == 0)
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
else
|
||||
ret = WOLFSSL_FAILURE;
|
||||
return WOLFSSL_SUCCESS;
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
/* Verify the signature with the digest. */
|
||||
switch (ctx->pctx->pkey->type) {
|
||||
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||
case EVP_PKEY_RSA: {
|
||||
int nid = md2nid(ctx->macType);
|
||||
if (nid < 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
return wolfSSL_RSA_verify(nid, digest, hashLen, sig,
|
||||
(unsigned int)siglen,
|
||||
ctx->pctx->pkey->rsa);
|
||||
}
|
||||
#endif /* NO_RSA */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
case EVP_PKEY_EC: {
|
||||
int ret;
|
||||
WOLFSSL_ECDSA_SIG *ecdsaSig;
|
||||
ecdsaSig = wolfSSL_d2i_ECDSA_SIG(NULL, &sig, (long)siglen);
|
||||
if (ecdsaSig == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
ret = wolfSSL_ECDSA_do_verify(digest, hashLen, ecdsaSig,
|
||||
ctx->pctx->pkey->ecc);
|
||||
wolfSSL_ECDSA_SIG_free(ecdsaSig);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ForceZero(&hmacCopy, sizeof(hmacCopy));
|
||||
ForceZero(digest, sizeof(digest));
|
||||
return ret;
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
#endif /* WOLFSSL_EVP_INCLUDED */
|
||||
|
||||
|
@@ -101,6 +101,9 @@ struct WOLFSSL_EC_KEY {
|
||||
char exSet; /* external set from internal ? */
|
||||
};
|
||||
|
||||
#define WOLFSSL_EC_KEY_LOAD_PRIVATE 1
|
||||
#define WOLFSSL_EC_KEY_LOAD_PUBLIC 2
|
||||
|
||||
WOLFSSL_API
|
||||
int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *curve,
|
||||
const WOLFSSL_EC_POINT *p,
|
||||
@@ -112,6 +115,9 @@ WOLFSSL_API
|
||||
int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key,
|
||||
const unsigned char* der, int derSz);
|
||||
WOLFSSL_API
|
||||
int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key,
|
||||
const unsigned char* der, int derSz, int opt);
|
||||
WOLFSSL_API
|
||||
void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key);
|
||||
WOLFSSL_API
|
||||
WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key);
|
||||
|
@@ -126,6 +126,7 @@ typedef union {
|
||||
#endif
|
||||
} WOLFSSL_Hasher;
|
||||
|
||||
typedef struct WOLFSSL_EVP_PKEY_CTX WOLFSSL_EVP_PKEY_CTX;
|
||||
|
||||
typedef struct WOLFSSL_EVP_MD_CTX {
|
||||
union {
|
||||
@@ -133,6 +134,7 @@ typedef struct WOLFSSL_EVP_MD_CTX {
|
||||
Hmac hmac;
|
||||
} hash;
|
||||
unsigned char macType;
|
||||
WOLFSSL_EVP_PKEY_CTX *pctx;
|
||||
} WOLFSSL_EVP_MD_CTX;
|
||||
|
||||
|
||||
@@ -219,11 +221,11 @@ typedef struct WOLFSSL_EVP_CIPHER_CTX {
|
||||
int lastUsed;
|
||||
} WOLFSSL_EVP_CIPHER_CTX;
|
||||
|
||||
typedef struct WOLFSSL_EVP_PKEY_CTX {
|
||||
struct WOLFSSL_EVP_PKEY_CTX {
|
||||
WOLFSSL_EVP_PKEY *pkey;
|
||||
int op; /* operation */
|
||||
int padding;
|
||||
} WOLFSSL_EVP_PKEY_CTX;
|
||||
};
|
||||
|
||||
typedef int WOLFSSL_ENGINE ;
|
||||
typedef WOLFSSL_ENGINE ENGINE;
|
||||
|
Reference in New Issue
Block a user