diff --git a/src/internal.c b/src/internal.c index 4608839eb..3eaa7d9d6 100644 --- a/src/internal.c +++ b/src/internal.c @@ -32243,6 +32243,184 @@ exit_gdpk: return ret; } #endif +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) +static int GetEcDiffieHellmanKea(WOLFSSL *ssl, + const byte *input, word32 size, DskeArgs *args) +{ + int ret; + byte b; +#ifdef HAVE_ECC + int curveId; +#endif + int curveOid; + word16 length; + + if ((args->idx - args->begin) + ENUM_LEN + OPAQUE16_LEN + + OPAQUE8_LEN > size) { + return BUFFER_ERROR; + } + + b = input[args->idx++]; + if (b != named_curve) { + return ECC_CURVETYPE_ERROR; + } + + args->idx += 1; /* curve type, eat leading 0 */ + b = input[args->idx++]; + if ((curveOid = CheckCurveId(b)) < 0) { + return ECC_CURVE_ERROR; + } + ssl->ecdhCurveOID = (word32) curveOid; +#if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) + ssl->namedGroup = 0; +#endif + + length = input[args->idx++]; + if ((args->idx - args->begin) + length > size) { + return BUFFER_ERROR; + } +#ifdef HAVE_CURVE25519 + if (ssl->ecdhCurveOID == ECC_X25519_OID) { + if (ssl->peerX25519Key == NULL) { + ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE25519, + (void **)&ssl->peerX25519Key); + if (ret != 0) { + return ret; + } + } + else if (ssl->peerX25519KeyPresent) { + ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE25519, ssl->peerX25519Key); + ssl->peerX25519KeyPresent = 0; + if (ret != 0) { + return ret; + } + } + + if ((ret = wc_curve25519_check_public(input + args->idx, length, + EC25519_LITTLE_ENDIAN)) != 0) { +#ifdef WOLFSSL_EXTRA_ALERTS + if (ret == WC_NO_ERR_TRACE(BUFFER_E)) + SendAlert(ssl, alert_fatal, decode_error); + else if (ret == WC_NO_ERR_TRACE(ECC_OUT_OF_RANGE_E)) + SendAlert(ssl, alert_fatal, bad_record_mac); + else { + SendAlert(ssl, alert_fatal, illegal_parameter); + } +#endif + return ECC_PEERKEY_ERROR; + } + + if (wc_curve25519_import_public_ex(input + args->idx, + length, ssl->peerX25519Key, + EC25519_LITTLE_ENDIAN) != 0) { + return ECC_PEERKEY_ERROR; + } + + args->idx += length; + ssl->peerX25519KeyPresent = 1; + return 0; + } +#endif +#ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + if (ssl->peerX448Key == NULL) { + ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448, + (void **)&ssl->peerX448Key); + if (ret != 0) { + return ret; + } + } + else if (ssl->peerX448KeyPresent) { + ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448, ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; + if (ret != 0) { + return ret; + } + } + + if ((ret = wc_curve448_check_public(input + args->idx, length, + EC448_LITTLE_ENDIAN)) != 0) { +#ifdef WOLFSSL_EXTRA_ALERTS + if (ret == WC_NO_ERR_TRACE(BUFFER_E)) + SendAlert(ssl, alert_fatal, decode_error); + else if (ret == WC_NO_ERR_TRACE(ECC_OUT_OF_RANGE_E)) + SendAlert(ssl, alert_fatal, bad_record_mac); + else { + SendAlert(ssl, alert_fatal, illegal_parameter); + } +#endif + return ECC_PEERKEY_ERROR; + } + + if (wc_curve448_import_public_ex(input + args->idx, + length, ssl->peerX448Key, + EC448_LITTLE_ENDIAN) != 0) { + return ECC_PEERKEY_ERROR; + } + + args->idx += length; + ssl->peerX448KeyPresent = 1; + return 0; + } +#endif +#ifdef HAVE_ECC + if (ssl->peerEccKey == NULL) { + ret = AllocKey(ssl, DYNAMIC_TYPE_ECC, (void **)&ssl->peerEccKey); + if (ret != 0) { + return ret; + } + } + else if (ssl->peerEccKeyPresent) { + ret = ReuseKey(ssl, DYNAMIC_TYPE_ECC, ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + if (ret != 0) { + return ret; + } + } + + curveId = wc_ecc_get_oid((word32) curveOid, NULL, NULL); + if (wc_ecc_import_x963_ex(input + args->idx, length, + ssl->peerEccKey, curveId) != 0) { +#ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, illegal_parameter); +#endif + return ECC_PEERKEY_ERROR; + } + + args->idx += length; + ssl->peerEccKeyPresent = 1; +#endif + return 0; +} +#endif /* def(HAVE_ECC) || def(HAVE_CURVE25519) || def(HAVE_CURVE448)) */ + +#if !defined(NO_PSK) +static int GetPSKServerHint(WOLFSSL *ssl, const byte *input, word32 size, + DskeArgs *args) +{ + int srvHintLen; + word16 length; + + if ((args->idx - args->begin) + OPAQUE16_LEN > size) { + return BUFFER_ERROR; + } + + ato16(input + args->idx, &length); + args->idx += OPAQUE16_LEN; + + if ((args->idx - args->begin) + length > size) { + return BUFFER_ERROR; + } + + /* get PSK server hint from the wire */ + srvHintLen = (int)min(length, MAX_PSK_ID_LEN); + XMEMCPY(ssl->arrays->server_hint, input + args->idx, (size_t)(srvHintLen)); + ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */ + + args->idx += length; + return 0; +} +#endif /* !defined(NO_PSK) */ /* handle processing of server_key_exchange (12) */ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, @@ -32310,26 +32488,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, #ifndef NO_PSK case psk_kea: { - int srvHintLen; - word16 length; - - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ato16(input + args->idx, &length); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - /* get PSK server hint from the wire */ - srvHintLen = (int)min(length, MAX_PSK_ID_LEN); - XMEMCPY(ssl->arrays->server_hint, input + args->idx, - (size_t)(srvHintLen)); - ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */ - args->idx += length; + ret = GetPSKServerHint(ssl, input, size, args); break; } #endif /* !NO_PSK */ @@ -32337,8 +32496,6 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, case diffie_hellman_kea: { ret = GetDhPublicKey(ssl, input, size, args); - if (ret != 0) - goto exit_dske; break; } #endif /* !NO_DH */ @@ -32346,181 +32503,16 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { - byte b; - #ifdef HAVE_ECC - int curveId; - #endif - int curveOid; - word16 length; - - if ((args->idx - args->begin) + ENUM_LEN + OPAQUE16_LEN + - OPAQUE8_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - b = input[args->idx++]; - if (b != named_curve) { - ERROR_OUT(ECC_CURVETYPE_ERROR, exit_dske); - } - - args->idx += 1; /* curve type, eat leading 0 */ - b = input[args->idx++]; - if ((curveOid = CheckCurveId(b)) < 0) { - ERROR_OUT(ECC_CURVE_ERROR, exit_dske); - } - ssl->ecdhCurveOID = (word32)curveOid; - #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) - ssl->namedGroup = 0; - #endif - - length = input[args->idx++]; - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - #ifdef HAVE_CURVE25519 - if (ssl->ecdhCurveOID == ECC_X25519_OID) { - if (ssl->peerX25519Key == NULL) { - ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE25519, - (void**)&ssl->peerX25519Key); - if (ret != 0) { - goto exit_dske; - } - } else if (ssl->peerX25519KeyPresent) { - ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE25519, - ssl->peerX25519Key); - ssl->peerX25519KeyPresent = 0; - if (ret != 0) { - goto exit_dske; - } - } - - if ((ret = wc_curve25519_check_public( - input + args->idx, length, - EC25519_LITTLE_ENDIAN)) != 0) { - #ifdef WOLFSSL_EXTRA_ALERTS - if (ret == WC_NO_ERR_TRACE(BUFFER_E)) - SendAlert(ssl, alert_fatal, decode_error); - else if (ret == WC_NO_ERR_TRACE(ECC_OUT_OF_RANGE_E)) - SendAlert(ssl, alert_fatal, bad_record_mac); - else { - SendAlert(ssl, alert_fatal, illegal_parameter); - } - #endif - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - if (wc_curve25519_import_public_ex(input + args->idx, - length, ssl->peerX25519Key, - EC25519_LITTLE_ENDIAN) != 0) { - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - args->idx += length; - ssl->peerX25519KeyPresent = 1; - break; - } - #endif - #ifdef HAVE_CURVE448 - if (ssl->ecdhCurveOID == ECC_X448_OID) { - if (ssl->peerX448Key == NULL) { - ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448, - (void**)&ssl->peerX448Key); - if (ret != 0) { - goto exit_dske; - } - } else if (ssl->peerX448KeyPresent) { - ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448, - ssl->peerX448Key); - ssl->peerX448KeyPresent = 0; - if (ret != 0) { - goto exit_dske; - } - } - - if ((ret = wc_curve448_check_public( - input + args->idx, length, - EC448_LITTLE_ENDIAN)) != 0) { - #ifdef WOLFSSL_EXTRA_ALERTS - if (ret == WC_NO_ERR_TRACE(BUFFER_E)) - SendAlert(ssl, alert_fatal, decode_error); - else if (ret == WC_NO_ERR_TRACE(ECC_OUT_OF_RANGE_E)) - SendAlert(ssl, alert_fatal, bad_record_mac); - else { - SendAlert(ssl, alert_fatal, illegal_parameter); - } - #endif - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - if (wc_curve448_import_public_ex(input + args->idx, - length, ssl->peerX448Key, - EC448_LITTLE_ENDIAN) != 0) { - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - args->idx += length; - ssl->peerX448KeyPresent = 1; - break; - } - #endif - #ifdef HAVE_ECC - if (ssl->peerEccKey == NULL) { - ret = AllocKey(ssl, DYNAMIC_TYPE_ECC, - (void**)&ssl->peerEccKey); - if (ret != 0) { - goto exit_dske; - } - } else if (ssl->peerEccKeyPresent) { - ret = ReuseKey(ssl, DYNAMIC_TYPE_ECC, ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; - if (ret != 0) { - goto exit_dske; - } - } - - curveId = wc_ecc_get_oid((word32)curveOid, NULL, NULL); - if (wc_ecc_import_x963_ex(input + args->idx, length, - ssl->peerEccKey, curveId) != 0) { - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, illegal_parameter); - #endif - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - args->idx += length; - ssl->peerEccKeyPresent = 1; - #endif + ret = GetEcDiffieHellmanKea(ssl, input, size, args); break; } #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #if !defined(NO_DH) && !defined(NO_PSK) case dhe_psk_kea: { - int srvHintLen; - word16 length; - - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ato16(input + args->idx, &length); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - /* get PSK server hint from the wire */ - srvHintLen = (int)min(length, MAX_PSK_ID_LEN); - XMEMCPY(ssl->arrays->server_hint, input + args->idx, - srvHintLen); - ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */ - args->idx += length; - - ret = GetDhPublicKey(ssl, input, size, args); - if (ret != 0) - goto exit_dske; + ret = GetPSKServerHint(ssl, input, size, args); + if (ret == 0) + ret = GetDhPublicKey(ssl, input, size, args); break; } #endif /* !NO_DH && !NO_PSK */ @@ -32528,169 +32520,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { - byte b; - int curveOid, curveId; - int srvHintLen; - word16 length; - - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ato16(input + args->idx, &length); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - /* get PSK server hint from the wire */ - srvHintLen = (int)min(length, MAX_PSK_ID_LEN); - XMEMCPY(ssl->arrays->server_hint, input + args->idx, - (size_t)(srvHintLen)); - ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */ - - args->idx += length; - - if ((args->idx - args->begin) + ENUM_LEN + OPAQUE16_LEN + - OPAQUE8_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - /* Check curve name and ID */ - b = input[args->idx++]; - if (b != named_curve) { - ERROR_OUT(ECC_CURVETYPE_ERROR, exit_dske); - } - - args->idx += 1; /* curve type, eat leading 0 */ - b = input[args->idx++]; - if ((curveOid = CheckCurveId(b)) < 0) { - ERROR_OUT(ECC_CURVE_ERROR, exit_dske); - } - ssl->ecdhCurveOID = (word32)curveOid; - #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) - ssl->namedGroup = 0; - #endif - - length = input[args->idx++]; - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - #ifdef HAVE_CURVE25519 - if (ssl->ecdhCurveOID == ECC_X25519_OID) { - if (ssl->peerX25519Key == NULL) { - ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE25519, - (void**)&ssl->peerX25519Key); - if (ret != 0) { - goto exit_dske; - } - } else if (ssl->peerX25519KeyPresent) { - ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE25519, - ssl->peerX25519Key); - ssl->peerX25519KeyPresent = 0; - if (ret != 0) { - goto exit_dske; - } - } - - if ((ret = wc_curve25519_check_public( - input + args->idx, length, - EC25519_LITTLE_ENDIAN)) != 0) { - #ifdef WOLFSSL_EXTRA_ALERTS - if (ret == WC_NO_ERR_TRACE(BUFFER_E)) - SendAlert(ssl, alert_fatal, decode_error); - else if (ret == WC_NO_ERR_TRACE(ECC_OUT_OF_RANGE_E)) - SendAlert(ssl, alert_fatal, bad_record_mac); - else { - SendAlert(ssl, alert_fatal, illegal_parameter); - } - #endif - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - if (wc_curve25519_import_public_ex(input + args->idx, - length, ssl->peerX25519Key, - EC25519_LITTLE_ENDIAN) != 0) { - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - args->idx += length; - ssl->peerX25519KeyPresent = 1; - break; - } - #endif - #ifdef HAVE_CURVE448 - if (ssl->ecdhCurveOID == ECC_X448_OID) { - if (ssl->peerX448Key == NULL) { - ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448, - (void**)&ssl->peerX448Key); - if (ret != 0) { - goto exit_dske; - } - } else if (ssl->peerX448KeyPresent) { - ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448, - ssl->peerX448Key); - ssl->peerX448KeyPresent = 0; - if (ret != 0) { - goto exit_dske; - } - } - - if ((ret = wc_curve448_check_public( - input + args->idx, length, - EC448_LITTLE_ENDIAN)) != 0) { - #ifdef WOLFSSL_EXTRA_ALERTS - if (ret == WC_NO_ERR_TRACE(BUFFER_E)) - SendAlert(ssl, alert_fatal, decode_error); - else if (ret == WC_NO_ERR_TRACE(ECC_OUT_OF_RANGE_E)) - SendAlert(ssl, alert_fatal, bad_record_mac); - else { - SendAlert(ssl, alert_fatal, illegal_parameter); - } - #endif - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - if (wc_curve448_import_public_ex(input + args->idx, - length, ssl->peerX448Key, - EC448_LITTLE_ENDIAN) != 0) { - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - args->idx += length; - ssl->peerX448KeyPresent = 1; - break; - } - #endif - #ifdef HAVE_ECC - if (ssl->peerEccKey == NULL) { - ret = AllocKey(ssl, DYNAMIC_TYPE_ECC, - (void**)&ssl->peerEccKey); - if (ret != 0) { - goto exit_dske; - } - } else if (ssl->peerEccKeyPresent) { - ret = ReuseKey(ssl, DYNAMIC_TYPE_ECC, ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; - if (ret != 0) { - goto exit_dske; - } - } - - curveId = wc_ecc_get_oid((word32)curveOid, NULL, NULL); - if (wc_ecc_import_x963_ex(input + args->idx, length, - ssl->peerEccKey, curveId) != 0) { - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, illegal_parameter); - #endif - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); - } - - args->idx += length; - ssl->peerEccKeyPresent = 1; - #endif + ret = GetPSKServerHint(ssl, input, size, args); + if (ret == 0) + ret = GetEcDiffieHellmanKea(ssl, input, size, args); break; } #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */