mirror of https://github.com/wolfSSL/wolfssh.git
Validate server's group
The client wasn't validating the DH group parameters in the KEX DH GEX Group message. This adds a function to perform the validation of the prime `p` to verify it is safe. (Prime and that ((p - 1) / 2) is prime.) Also adds a test to a known unsafe prime and known safe prime to verify the validate function. Affected function: DoKexDhGexGroup. Issue: F-1688pull/922/head
parent
543a6c2a2f
commit
16ddcd9764
160
src/internal.c
160
src/internal.c
|
|
@ -185,6 +185,10 @@ Flags:
|
|||
WOLFSSH_NO_CURVE25519_SHA256
|
||||
Set when Curve25519 or SHA2-256 are disabled in wolfSSL. Set to disable use
|
||||
of Curve25519 key exchange.
|
||||
WOLFSSH_MR_ROUNDS
|
||||
Set the number of Miller-Rabin rounds used when the client checks the
|
||||
server's prime group when using GEX key exchange. The default is 8. More
|
||||
rounds are better, but also takes a lot longer.
|
||||
*/
|
||||
|
||||
static const char sshProtoIdStr[] = "SSH-2.0-wolfSSHv"
|
||||
|
|
@ -6284,6 +6288,141 @@ static int DoKexDhGexRequest(WOLFSSH* ssh,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Validate a DH GEX group received from the server against RFC 4419 sec. 3
|
||||
* requirements, with an additional hardening/policy check:
|
||||
* - p's bit length falls within the client's requested [minBits, maxBits]
|
||||
* - p is odd and probably prime
|
||||
* - (additional hardening requirement) (p-1)/2 is also probably prime,
|
||||
* i.e. p is a safe prime, which bounds the order of g to q or 2q and
|
||||
* closes the small-subgroup attack
|
||||
* Returns WS_SUCCESS if the group is acceptable.
|
||||
*/
|
||||
static int ValidateKexDhGexGroup(const byte* primeGroup, word32 primeGroupSz,
|
||||
const byte* generator, word32 generatorSz,
|
||||
word32 minBits, word32 maxBits, WC_RNG* rng)
|
||||
{
|
||||
mp_int p, g, q;
|
||||
int pgqInit = 0;
|
||||
int bits;
|
||||
int isPrime = MP_NO;
|
||||
int ret = WS_SUCCESS;
|
||||
|
||||
if (primeGroup == NULL || primeGroupSz == 0
|
||||
|| generator == NULL || generatorSz == 0
|
||||
|| rng == NULL)
|
||||
ret = WS_BAD_ARGUMENT;
|
||||
|
||||
/*
|
||||
* Check the bounds on the size of the flat prime group and generator
|
||||
* values. The prime group shall be LE maxBits. The generator size
|
||||
* shall be LE prime group size. This is a check on the sizes of values
|
||||
* sent by the peer before reading them in and checking them as mp_ints.
|
||||
*/
|
||||
if (ret == WS_SUCCESS) {
|
||||
word32 maxBytes = (maxBits / 8) + ((maxBits % 8) ? 1 : 0);
|
||||
/* Adjust the sizes for signed padding. */
|
||||
word32 adjPrimeGroupSz = primeGroupSz - ((primeGroup[0] == 0) ? 1 : 0);
|
||||
word32 adjGeneratorSz = generatorSz - ((generator[0] == 0) ? 1 : 0);
|
||||
|
||||
if (adjPrimeGroupSz > maxBytes || adjGeneratorSz > adjPrimeGroupSz) {
|
||||
ret = WS_DH_SIZE_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (mp_init_multi(&p, &g, &q, NULL, NULL, NULL) != MP_OKAY) {
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
else {
|
||||
pgqInit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (mp_read_unsigned_bin(&p, primeGroup, primeGroupSz) != MP_OKAY)
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (mp_read_unsigned_bin(&g, generator, generatorSz) != MP_OKAY)
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
bits = mp_count_bits(&p);
|
||||
if (bits < (int)minBits || bits > (int)maxBits) {
|
||||
WLOG(WS_LOG_DEBUG,
|
||||
"DH GEX: prime size %d outside requested [%u, %u]",
|
||||
bits, minBits, maxBits);
|
||||
ret = WS_DH_SIZE_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (!mp_isodd(&p)) {
|
||||
WLOG(WS_LOG_DEBUG, "DH GEX: prime is even");
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2 <= g: reject g == 0 and g == 1. */
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (mp_cmp_d(&g, 1) != MP_GT) {
|
||||
WLOG(WS_LOG_DEBUG, "DH GEX: generator < 2");
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/* g <= p - 2: reject g == p - 1 (order 2) and anything larger. */
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (mp_sub_d(&p, 1, &q) != MP_OKAY)
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
else if (mp_cmp(&g, &q) != MP_LT) {
|
||||
WLOG(WS_LOG_DEBUG, "DH GEX: generator >= p - 1");
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Miller-Rabin: p must be prime. */
|
||||
if (ret == WS_SUCCESS) {
|
||||
isPrime = MP_NO;
|
||||
ret = mp_prime_is_prime_ex(&p, WOLFSSH_MR_ROUNDS, &isPrime, rng);
|
||||
if (ret != MP_OKAY || isPrime == MP_NO) {
|
||||
WLOG(WS_LOG_DEBUG, "DH GEX: p is not prime");
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
else {
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Safe prime check: q = (p - 1) / 2 must also be prime. */
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (mp_sub_d(&p, 1, &q) != MP_OKAY || mp_div_2(&q, &q) != MP_OKAY)
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
if (ret == WS_SUCCESS) {
|
||||
isPrime = MP_NO;
|
||||
ret = mp_prime_is_prime_ex(&q, WOLFSSH_MR_ROUNDS, &isPrime, rng);
|
||||
if (ret != MP_OKAY || isPrime == MP_NO) {
|
||||
WLOG(WS_LOG_DEBUG, "DH GEX: (p-1)/2 is not prime, p is not safe");
|
||||
ret = WS_CRYPTO_FAILED;
|
||||
}
|
||||
else {
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (pgqInit) {
|
||||
mp_clear(&q);
|
||||
mp_clear(&g);
|
||||
mp_clear(&p);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int DoKexDhGexGroup(WOLFSSH* ssh,
|
||||
byte* buf, word32 len, word32* idx)
|
||||
{
|
||||
|
|
@ -6300,13 +6439,22 @@ static int DoKexDhGexGroup(WOLFSSH* ssh,
|
|||
if (ret == WS_SUCCESS) {
|
||||
begin = *idx;
|
||||
ret = GetMpint(&primeGroupSz, &primeGroup, buf, len, &begin);
|
||||
if (ret == WS_SUCCESS && primeGroupSz > (MAX_KEX_KEY_SZ + 1))
|
||||
if (ret == WS_SUCCESS && primeGroupSz > (MAX_KEX_KEY_SZ + 1)) {
|
||||
ret = WS_DH_SIZE_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS)
|
||||
ret = GetMpint(&generatorSz, &generator, buf, len, &begin);
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
ret = ValidateKexDhGexGroup(primeGroup, primeGroupSz,
|
||||
generator, generatorSz,
|
||||
ssh->handshake->dhGexMinSz,
|
||||
ssh->handshake->dhGexMaxSz,
|
||||
ssh->rng);
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (ssh->handshake->primeGroup)
|
||||
WFREE(ssh->handshake->primeGroup, ssh->ctx->heap, DYNTYPE_MPINT);
|
||||
|
|
@ -6340,7 +6488,17 @@ static int DoKexDhGexGroup(WOLFSSH* ssh,
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSH_TEST_INTERNAL
|
||||
int wolfSSH_TestValidateKexDhGexGroup(const byte* primeGroup,
|
||||
word32 primeGroupSz, const byte* generator, word32 generatorSz,
|
||||
word32 minBits, word32 maxBits, WC_RNG* rng)
|
||||
{
|
||||
return ValidateKexDhGexGroup(primeGroup, primeGroupSz,
|
||||
generator, generatorSz, minBits, maxBits, rng);
|
||||
}
|
||||
#endif
|
||||
#endif /* !WOLFSSH_NO_DH_GEX_SHA256 */
|
||||
|
||||
|
||||
static int DoIgnore(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
|
||||
|
|
|
|||
194
tests/unit.c
194
tests/unit.c
|
|
@ -31,7 +31,10 @@
|
|||
#include <stdio.h>
|
||||
#include <wolfssh/ssh.h>
|
||||
#include <wolfssh/keygen.h>
|
||||
#include <wolfssh/error.h>
|
||||
#include <wolfssh/internal.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
#include <wolfssl/wolfcrypt/integer.h>
|
||||
#include <wolfssl/wolfcrypt/hmac.h>
|
||||
|
||||
#define WOLFSSH_TEST_HEX2BIN
|
||||
|
|
@ -439,6 +442,190 @@ done:
|
|||
#endif /* WOLFSSH_TEST_INTERNAL && any HMAC SHA variant enabled */
|
||||
|
||||
|
||||
#if defined(WOLFSSH_TEST_INTERNAL) && !defined(WOLFSSH_NO_DH_GEX_SHA256)
|
||||
|
||||
typedef struct {
|
||||
const char* candidate;
|
||||
const char* generator;
|
||||
word32 minBits;
|
||||
word32 maxBits;
|
||||
int expectedResult;
|
||||
} PrimeTestVector;
|
||||
|
||||
static const PrimeTestVector primeTestVectors[] = {
|
||||
{
|
||||
/*
|
||||
* For testing the ValidateKexDhGexGroup() function, we need to
|
||||
* verify that the function detects unsafe primes. The following
|
||||
* unsafe prime is the prime used with GOST-ECC. (RFC 7836) It is
|
||||
* prime and fine for its application. It isn't safe for DH, as
|
||||
* q = (p-1)/2 is not prime.
|
||||
*/
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7",
|
||||
"02",
|
||||
512, 8192, WS_CRYPTO_FAILED
|
||||
},
|
||||
{
|
||||
/*
|
||||
* We need to verify that the function detects safe primes. The
|
||||
* following safePrime is the MODP 2048-bit group from RFC 3526.
|
||||
*/
|
||||
"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74"
|
||||
"020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f1437"
|
||||
"4fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed"
|
||||
"ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf05"
|
||||
"98da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb"
|
||||
"9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3b"
|
||||
"e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf695581718"
|
||||
"3995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff",
|
||||
"02",
|
||||
2048, 8192, WS_SUCCESS
|
||||
},
|
||||
{
|
||||
/*
|
||||
* This checks for g = p - 1.
|
||||
*/
|
||||
"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74"
|
||||
"020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f1437"
|
||||
"4fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed"
|
||||
"ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf05"
|
||||
"98da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb"
|
||||
"9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3b"
|
||||
"e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf695581718"
|
||||
"3995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff",
|
||||
"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74"
|
||||
"020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f1437"
|
||||
"4fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed"
|
||||
"ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf05"
|
||||
"98da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb"
|
||||
"9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3b"
|
||||
"e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf695581718"
|
||||
"3995497cea956ae515d2261898fa051015728e5a8aacaa68fffffffffffffffe",
|
||||
2048, 8192, WS_CRYPTO_FAILED
|
||||
},
|
||||
{
|
||||
/*
|
||||
* This checks for g = 1.
|
||||
*/
|
||||
"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74"
|
||||
"020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f1437"
|
||||
"4fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed"
|
||||
"ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf05"
|
||||
"98da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb"
|
||||
"9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3b"
|
||||
"e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf695581718"
|
||||
"3995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff",
|
||||
"01",
|
||||
2048, 8192, WS_CRYPTO_FAILED
|
||||
},
|
||||
{
|
||||
/*
|
||||
* This checks prime size less than minBits.
|
||||
*/
|
||||
"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74"
|
||||
"020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f1437"
|
||||
"4fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed"
|
||||
"ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf05"
|
||||
"98da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb"
|
||||
"9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3b"
|
||||
"e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf695581718"
|
||||
"3995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff",
|
||||
"02",
|
||||
3072, 8192, WS_DH_SIZE_E
|
||||
},
|
||||
{
|
||||
/*
|
||||
* This checks prime size greater than maxBits.
|
||||
*/
|
||||
"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74"
|
||||
"020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f1437"
|
||||
"4fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed"
|
||||
"ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf05"
|
||||
"98da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb"
|
||||
"9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3b"
|
||||
"e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf695581718"
|
||||
"3995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff",
|
||||
"02",
|
||||
512, 1024, WS_DH_SIZE_E
|
||||
},
|
||||
{
|
||||
/*
|
||||
* This checks for even p.
|
||||
*/
|
||||
"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74"
|
||||
"020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f1437"
|
||||
"4fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed"
|
||||
"ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf05"
|
||||
"98da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb"
|
||||
"9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3b"
|
||||
"e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf695581718"
|
||||
"3995497cea956ae515d2261898fa051015728e5a8aacaa68fffffffffffffffe",
|
||||
"02",
|
||||
2048, 8192, WS_CRYPTO_FAILED
|
||||
},
|
||||
{
|
||||
/*
|
||||
* A well known composite number that breaks some MR implementations.
|
||||
* This is calculated by wolfCrypt for one of its prime tests.
|
||||
*/
|
||||
"000000000088cbf655be37a612fa535b4a9b81d394854ecbedfe1a4afbecdc7b"
|
||||
"a6a263549dd3c17882b054329384962576e7c5aa281e04ab5a0e7245584ad324"
|
||||
"9c7ac4de7caf5663bae95f6bb9e8bec4124e04d82eac54a246bda49a5c5c2a1b"
|
||||
"366ef8c085fc7c5f87478a55832d1b2184154c24260df67561d17c4359724403",
|
||||
"02",
|
||||
512, 8192, WS_CRYPTO_FAILED
|
||||
},
|
||||
};
|
||||
|
||||
static int test_DhGexGroupValidate(void)
|
||||
{
|
||||
WC_RNG rng;
|
||||
const PrimeTestVector* tv;
|
||||
byte* candidate;
|
||||
byte* generator;
|
||||
word32 candidateSz;
|
||||
word32 generatorSz;
|
||||
int tc = (int)(sizeof(primeTestVectors)/sizeof(primeTestVectors[0]));
|
||||
int result = 0, ret, i;
|
||||
|
||||
if (wc_InitRng(&rng) != 0) {
|
||||
printf("DhGexGroupValidate: wc_InitRng failed\n");
|
||||
return -110;
|
||||
}
|
||||
|
||||
for (i = 0, tv = primeTestVectors; i < tc && !result; i++, tv++) {
|
||||
candidate = NULL;
|
||||
candidateSz = 0;
|
||||
generator = NULL;
|
||||
generatorSz = 0;
|
||||
|
||||
ret = ConvertHexToBin(tv->candidate, &candidate, &candidateSz,
|
||||
tv->generator, &generator, &generatorSz,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (ret != 0) {
|
||||
result = -113;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = wolfSSH_TestValidateKexDhGexGroup(candidate, candidateSz,
|
||||
generator, generatorSz, tv->minBits, tv->maxBits, &rng);
|
||||
if (ret != tv->expectedResult) {
|
||||
printf("DhGexGroupValidate: validator returned %d, expected %d\n",
|
||||
ret, tv->expectedResult);
|
||||
result = -121;
|
||||
}
|
||||
|
||||
FreeBins(candidate, generator, NULL, NULL);
|
||||
}
|
||||
|
||||
wc_FreeRng(&rng);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSH_TEST_INTERNAL && !WOLFSSH_NO_DH_GEX_SHA256 */
|
||||
|
||||
|
||||
/* Error Code And Message Test */
|
||||
|
||||
static int test_Errors(void)
|
||||
|
|
@ -520,6 +707,13 @@ int wolfSSH_UnitTest(int argc, char** argv)
|
|||
testResult = testResult || unitResult;
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSH_TEST_INTERNAL) && !defined(WOLFSSH_NO_DH_GEX_SHA256)
|
||||
unitResult = test_DhGexGroupValidate();
|
||||
printf("DhGexGroupValidate: %s\n",
|
||||
(unitResult == 0 ? "SUCCESS" : "FAILED"));
|
||||
testResult = testResult || unitResult;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSH_KEYGEN
|
||||
#ifndef WOLFSSH_NO_RSA
|
||||
unitResult = test_RsaKeyGen();
|
||||
|
|
|
|||
|
|
@ -476,6 +476,9 @@ enum NameIdType {
|
|||
#define MAX_KEX_KEY_SZ (WOLFSSH_DEFAULT_GEXDH_MAX / 8)
|
||||
#endif
|
||||
#endif
|
||||
#ifndef WOLFSSH_MR_ROUNDS
|
||||
#define WOLFSSH_MR_ROUNDS 8
|
||||
#endif
|
||||
#ifndef WOLFSSH_MAX_FILE_SIZE
|
||||
#define WOLFSSH_MAX_FILE_SIZE (1024ul * 1024ul * 4)
|
||||
#endif
|
||||
|
|
@ -1324,7 +1327,12 @@ enum WS_MessageIdLimits {
|
|||
WOLFSSH_API int wolfSSH_TestIsMessageAllowed(WOLFSSH* ssh, byte msg,
|
||||
byte state);
|
||||
WOLFSSH_API int wolfSSH_TestDoReceive(WOLFSSH* ssh);
|
||||
#endif
|
||||
#ifndef WOLFSSH_NO_DH_GEX_SHA256
|
||||
WOLFSSH_API int wolfSSH_TestValidateKexDhGexGroup(const byte* primeGroup,
|
||||
word32 primeGroupSz, const byte* generator, word32 generatorSz,
|
||||
word32 minBits, word32 maxBits, WC_RNG* rng);
|
||||
#endif /* !WOLFSSH_NO_DH_GEX_SHA256 */
|
||||
#endif /* WOLFSSH_TEST_INTERNAL */
|
||||
|
||||
/* dynamic memory types */
|
||||
enum WS_DynamicTypes {
|
||||
|
|
|
|||
Loading…
Reference in New Issue