Moved wolfSSL_GetEccKey logic to internal.c and use only for PK_CALLBACK. Added other ECC key info to the EccSharedSecretCb. Cleanup of the "if (ssl->ctx->EccSharedSecretCb == NULL)" logic to revert indent so changes are minimized. Removed new wolfSSL_GetEccKey API.

This commit is contained in:
David Garske
2016-12-05 11:36:53 -08:00
parent eaca90db28
commit 45d26876c8
4 changed files with 249 additions and 216 deletions

View File

@@ -2965,6 +2965,62 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out,
return ret; return ret;
} }
#ifdef HAVE_PK_CALLBACKS
/* Gets ECC key for shared secret callback testing
* Client side: returns peer key
* Server side: returns private key
*/
static int EccGetKey(WOLFSSL* ssl, byte* otherKeyDer,
word32* otherKeySz, word32* otherKeyId)
{
int ret = NO_PEER_KEY;
ecc_key* otherKey = NULL;
if (ssl == NULL || otherKeyDer == NULL || otherKeySz == NULL) {
return BAD_FUNC_ARG;
}
if (ssl->options.side == WOLFSSL_CLIENT_END) {
if (ssl->specs.static_ecdh) {
if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
!ssl->peerEccDsaKey->dp) {
return NO_PEER_KEY;
}
otherKey = (struct ecc_key*)ssl->peerEccDsaKey;
}
else {
if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
!ssl->peerEccKey->dp) {
return NO_PEER_KEY;
}
otherKey = (struct ecc_key*)ssl->peerEccKey;
}
}
else if (ssl->options.side == WOLFSSL_SERVER_END) {
if (ssl->specs.static_ecdh) {
if (ssl->sigKey == NULL) {
return NO_PRIVATE_KEY;
}
otherKey = (struct ecc_key*)ssl->sigKey;
}
else {
if (!ssl->eccTempKeyPresent) {
return NO_PRIVATE_KEY;
}
otherKey = (struct ecc_key*)ssl->eccTempKey;
}
}
if (otherKey) {
ret = wc_ecc_export_x963(otherKey, otherKeyDer, otherKeySz);
if (otherKeyId)
*otherKeyId = otherKey->dp->id;
}
return ret;
}
#endif /* HAVE_PK_CALLBACKS */
int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key,
byte* pubKeyDer, word32* pubKeySz, byte* out, word32* outlen, byte* pubKeyDer, word32* pubKeySz, byte* out, word32* outlen,
int side, void* ctx) int side, void* ctx)
@@ -2981,8 +3037,15 @@ int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key,
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb) { if (ssl->ctx->EccSharedSecretCb) {
ret = ssl->ctx->EccSharedSecretCb(ssl, pubKeyDer, pubKeySz, byte* otherKeyDer = NULL;
out, outlen, side, ctx); word32 otherKeySz = 0;
word32 otherKeyId = ECC_CURVE_DEF;
ret = EccGetKey(ssl, otherKeyDer, &otherKeySz, &otherKeyId);
if (ret == 0) {
ret = ssl->ctx->EccSharedSecretCb(ssl, otherKeyDer, otherKeySz,
otherKeyId, pubKeyDer, pubKeySz, out, outlen, side, ctx);
}
} }
else else
#endif #endif
@@ -15452,9 +15515,12 @@ int SendClientKeyExchange(WOLFSSL* ssl)
} }
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL) /* if callback then use it for shared secret */
if (ssl->ctx->EccSharedSecretCb != NULL) {
break;
}
#endif #endif
{
/* create private key */ /* create private key */
ssl->sigKey = XMALLOC(sizeof(ecc_key), ssl->sigKey = XMALLOC(sizeof(ecc_key),
ssl->heap, DYNAMIC_TYPE_ECC); ssl->heap, DYNAMIC_TYPE_ECC);
@@ -15468,8 +15534,8 @@ int SendClientKeyExchange(WOLFSSL* ssl)
if (ret != 0) { if (ret != 0) {
goto exit_scke; goto exit_scke;
} }
ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, ssl->peerEccKey); ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey,
} ssl->peerEccKey);
break; break;
#endif /* HAVE_ECC && !NO_PSK */ #endif /* HAVE_ECC && !NO_PSK */
#ifdef HAVE_NTRU #ifdef HAVE_NTRU
@@ -15481,16 +15547,20 @@ int SendClientKeyExchange(WOLFSSL* ssl)
#endif /* HAVE_NTRU */ #endif /* HAVE_NTRU */
#ifdef HAVE_ECC #ifdef HAVE_ECC
case ecc_diffie_hellman_kea: case ecc_diffie_hellman_kea:
{
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL)
#endif
{ {
ecc_key* peerKey; ecc_key* peerKey;
#ifdef HAVE_PK_CALLBACKS
/* if callback then use it for shared secret */
if (ssl->ctx->EccSharedSecretCb != NULL) {
break;
}
#endif
if (ssl->specs.static_ecdh) { if (ssl->specs.static_ecdh) {
/* TODO: EccDsa is really fixed Ecc change naming */ /* TODO: EccDsa is really fixed Ecc change naming */
if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || if (!ssl->peerEccDsaKey ||
!ssl->peerEccDsaKeyPresent ||
!ssl->peerEccDsaKey->dp) { !ssl->peerEccDsaKey->dp) {
ERROR_OUT(NO_PEER_KEY, exit_scke); ERROR_OUT(NO_PEER_KEY, exit_scke);
} }
@@ -15521,7 +15591,6 @@ int SendClientKeyExchange(WOLFSSL* ssl)
goto exit_scke; goto exit_scke;
} }
ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, peerKey); ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, peerKey);
}
break; break;
} }
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */
@@ -15677,16 +15746,18 @@ int SendClientKeyExchange(WOLFSSL* ssl)
*length = MAX_ENCRYPT_SZ; *length = MAX_ENCRYPT_SZ;
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL) /* if callback then use it for shared secret */
if (ssl->ctx->EccSharedSecretCb != NULL) {
break;
}
#endif #endif
{
/* Place ECC key in buffer, leaving room for size */ /* Place ECC key in buffer, leaving room for size */
ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey,
output + OPAQUE8_LEN, length); output + OPAQUE8_LEN, length);
if (ret != 0) { if (ret != 0) {
ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
} }
}
break; break;
} }
#endif /* HAVE_ECC && !NO_PSK */ #endif /* HAVE_ECC && !NO_PSK */
@@ -15708,16 +15779,18 @@ int SendClientKeyExchange(WOLFSSL* ssl)
case ecc_diffie_hellman_kea: case ecc_diffie_hellman_kea:
{ {
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL) /* if callback then use it for shared secret */
if (ssl->ctx->EccSharedSecretCb != NULL) {
break;
}
#endif #endif
{
/* Place ECC key in buffer, leaving room for size */ /* Place ECC key in buffer, leaving room for size */
ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey,
encSecret + OPAQUE8_LEN, &encSz); encSecret + OPAQUE8_LEN, &encSz);
if (ret != 0) { if (ret != 0) {
ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
} }
}
break; break;
} }
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */
@@ -20146,9 +20219,12 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
} }
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL) /* if callback then use it for shared secret */
if (ssl->ctx->EccSharedSecretCb != NULL) {
break;
}
#endif #endif
{
if (!ssl->specs.static_ecdh && if (!ssl->specs.static_ecdh &&
ssl->eccTempKeyPresent == 0) { ssl->eccTempKeyPresent == 0) {
WOLFSSL_MSG("Ecc ephemeral key not made correctly"); WOLFSSL_MSG("Ecc ephemeral key not made correctly");
@@ -20157,8 +20233,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
/* alloc/init on demand */ /* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->peerEccKey = (ecc_key*)XMALLOC(
ssl->heap, DYNAMIC_TYPE_ECC); sizeof(ecc_key), ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error"); WOLFSSL_MSG("PeerEccKey Memory error");
ERROR_OUT(MEMORY_E, exit_dcke); ERROR_OUT(MEMORY_E, exit_dcke);
@@ -20178,14 +20254,12 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
} }
} }
if (wc_ecc_import_x963_ex(input + idx, length, ssl->peerEccKey, if (wc_ecc_import_x963_ex(input + idx, length,
private_key->dp->id)) { ssl->peerEccKey, private_key->dp->id)) {
ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
} }
ssl->peerEccKeyPresent = 1; ssl->peerEccKeyPresent = 1;
}
break; break;
} }
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */
@@ -20287,9 +20361,12 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
} }
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL) /* if callback then use it for shared secret */
if (ssl->ctx->EccSharedSecretCb != NULL) {
break;
}
#endif #endif
{
if (ssl->eccTempKeyPresent == 0) { if (ssl->eccTempKeyPresent == 0) {
WOLFSSL_MSG("Ecc ephemeral key not made correctly"); WOLFSSL_MSG("Ecc ephemeral key not made correctly");
ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
@@ -20297,8 +20374,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
/* alloc/init on demand */ /* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->peerEccKey = (ecc_key*)XMALLOC(
ssl->heap, DYNAMIC_TYPE_ECC); sizeof(ecc_key), ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->peerEccKey == NULL) { if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error"); WOLFSSL_MSG("PeerEccKey Memory error");
ERROR_OUT(MEMORY_E, exit_dcke); ERROR_OUT(MEMORY_E, exit_dcke);
@@ -20325,7 +20402,6 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
} }
ssl->peerEccKeyPresent = 1; ssl->peerEccKeyPresent = 1;
}
break; break;
} }
#endif /* HAVE_ECC && !NO_PSK */ #endif /* HAVE_ECC && !NO_PSK */

View File

@@ -959,50 +959,6 @@ int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
return SSL_SUCCESS; return SSL_SUCCESS;
} }
/* Gets ECC key for shared secret callback testing
* Client side: returns peer key
* Server side: returns private key
*/
int wolfSSL_GetEccKey(WOLFSSL* ssl, struct ecc_key** key)
{
if (ssl == NULL || key == NULL) {
return BAD_FUNC_ARG;
}
if (ssl->options.side == WOLFSSL_CLIENT_END) {
if (ssl->specs.static_ecdh) {
if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
!ssl->peerEccDsaKey->dp) {
return NO_PEER_KEY;
}
*key = (struct ecc_key*)ssl->peerEccDsaKey;
}
else {
if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
!ssl->peerEccKey->dp) {
return NO_PEER_KEY;
}
*key = (struct ecc_key*)ssl->peerEccKey;
}
}
else if (ssl->options.side == WOLFSSL_SERVER_END) {
if (ssl->specs.static_ecdh) {
if (ssl->sigKey == NULL) {
return NO_PRIVATE_KEY;
}
*key = (struct ecc_key*)ssl->sigKey;
}
else {
if (!ssl->eccTempKeyPresent) {
return NO_PRIVATE_KEY;
}
*key = (struct ecc_key*)ssl->eccTempKey;
}
}
return 0;
}
#endif /* !NO_RSA */ #endif /* !NO_RSA */
#ifndef NO_RSA #ifndef NO_RSA

View File

@@ -1043,8 +1043,6 @@ WOLFSSL_API int wolfSSL_SetMinRsaKey_Sz(WOLFSSL*, short);
#ifdef HAVE_ECC #ifdef HAVE_ECC
WOLFSSL_API int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX*, short); WOLFSSL_API int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX*, short);
WOLFSSL_API int wolfSSL_SetMinEccKey_Sz(WOLFSSL*, short); WOLFSSL_API int wolfSSL_SetMinEccKey_Sz(WOLFSSL*, short);
struct ecc_key;
WOLFSSL_API int wolfSSL_GetEccKey(WOLFSSL*, struct ecc_key**);
#endif /* NO_RSA */ #endif /* NO_RSA */
WOLFSSL_API int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL*, unsigned short); WOLFSSL_API int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL*, unsigned short);
@@ -1344,6 +1342,8 @@ WOLFSSL_API void wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx);
WOLFSSL_API void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl); WOLFSSL_API void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl);
typedef int (*CallbackEccSharedSecret)(WOLFSSL* ssl, typedef int (*CallbackEccSharedSecret)(WOLFSSL* ssl,
const unsigned char* otherKeyDer, unsigned int otherKeySz,
unsigned int otherKeyId,
unsigned char* pubKeyDer, unsigned int* pubKeySz, unsigned char* pubKeyDer, unsigned int* pubKeySz,
unsigned char* out, unsigned int* outlen, unsigned char* out, unsigned int* outlen,
int side, void* ctx); /* side is WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END */ int side, void* ctx); /* side is WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END */

View File

@@ -1706,51 +1706,51 @@ static INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
} }
static INLINE int myEccSharedSecret(WOLFSSL* ssl, static INLINE int myEccSharedSecret(WOLFSSL* ssl,
const unsigned char* otherKeyDer, unsigned int otherKeySz,
unsigned int otherKeyId,
unsigned char* pubKeyDer, unsigned int* pubKeySz, unsigned char* pubKeyDer, unsigned int* pubKeySz,
unsigned char* out, unsigned int* outlen, unsigned char* out, unsigned int* outlen,
int side, void* ctx) int side, void* ctx)
{ {
int ret; int ret;
ecc_key* privKey; ecc_key privKey;
ecc_key* pubKey; ecc_key pubKey;
ecc_key tmpKey;
(void)ssl; (void)ssl;
(void)ctx; (void)ctx;
ret = wc_ecc_init(&tmpKey); ret = wc_ecc_init(&privKey);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
ret = wc_ecc_init(&pubKey);
if (ret != 0) {
wc_ecc_free(&privKey);
return ret;
}
/* for client: create and export public key */ /* for client: create and export public key */
if (side == WOLFSSL_CLIENT_END) { if (side == WOLFSSL_CLIENT_END) {
WC_RNG rng; WC_RNG rng;
ret = wc_InitRng(&rng); ret = wc_InitRng(&rng);
if (ret == 0) { if (ret == 0) {
ret = wolfSSL_GetEccKey(ssl, &pubKey); ret = wc_ecc_import_x963_ex(otherKeyDer, otherKeySz, &pubKey,
if (ret != 0) { otherKeyId);
return ret; if (ret == 0)
} ret = wc_ecc_make_key_ex(&rng, 0, &privKey, otherKeyId);
privKey = &tmpKey; if (ret == 0)
ret = wc_ecc_export_x963(&privKey, pubKeyDer, pubKeySz);
ret = wc_ecc_make_key_ex(&rng, 0, privKey, pubKey->dp->id);
if (ret == 0) {
ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz);
}
wc_FreeRng(&rng); wc_FreeRng(&rng);
} }
} }
/* for server: import public key */ /* for server: import public key */
else if (side == WOLFSSL_SERVER_END) { else if (side == WOLFSSL_SERVER_END) {
ret = wolfSSL_GetEccKey(ssl, &privKey); ret = wc_ecc_import_x963_ex(otherKeyDer, otherKeySz, &privKey,
if (ret != 0) { otherKeyId);
return ret; if (ret == 0)
} ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, &pubKey,
pubKey = &tmpKey; otherKeyId);
ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, privKey->dp->id);
} }
else { else {
ret = -1; ret = -1;
@@ -1758,10 +1758,11 @@ static INLINE int myEccSharedSecret(WOLFSSL* ssl,
/* generate shared secret and return it */ /* generate shared secret and return it */
if (ret == 0) { if (ret == 0) {
ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen); ret = wc_ecc_shared_secret(&privKey, &pubKey, out, outlen);
} }
wc_ecc_free(&tmpKey); wc_ecc_free(&privKey);
wc_ecc_free(&pubKey);
return ret; return ret;
} }