mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
Calculate cookie in SendStatelessReplyDtls13()
Not touching ssl->hsHashes while in stateless mode
This commit is contained in:
32
src/dtls.c
32
src/dtls.c
@@ -492,9 +492,10 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch,
|
|||||||
#endif
|
#endif
|
||||||
CipherSuite cs;
|
CipherSuite cs;
|
||||||
CipherSpecs specs;
|
CipherSpecs specs;
|
||||||
|
byte cookieHash[WC_MAX_DIGEST_SIZE];
|
||||||
|
int cookieHashSz;
|
||||||
|
|
||||||
XMEMSET(&cs, 0, sizeof(cs));
|
XMEMSET(&cs, 0, sizeof(cs));
|
||||||
XMEMSET(&specs, 0, sizeof(specs));
|
|
||||||
|
|
||||||
/* We need to echo the session ID sent by the client */
|
/* We need to echo the session ID sent by the client */
|
||||||
if (ch->sessionId.size > ID_LEN) {
|
if (ch->sessionId.size > ID_LEN) {
|
||||||
@@ -502,12 +503,6 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch,
|
|||||||
ERROR_OUT(INVALID_PARAMETER, dtls13_cleanup);
|
ERROR_OUT(INVALID_PARAMETER, dtls13_cleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hashes are reset in SendTls13ServerHello when sending a HRR */
|
|
||||||
ret = Dtls13HashHandshakeType((WOLFSSL*)ssl, ch->raw, ch->length,
|
|
||||||
client_hello);
|
|
||||||
if (ret != 0)
|
|
||||||
goto dtls13_cleanup;
|
|
||||||
|
|
||||||
/* Populate the suites struct to find a common ciphersuite */
|
/* Populate the suites struct to find a common ciphersuite */
|
||||||
XMEMSET(&suites, 0, sizeof(suites));
|
XMEMSET(&suites, 0, sizeof(suites));
|
||||||
suites.suiteSz = (word16)ch->cipherSuite.size;
|
suites.suiteSz = (word16)ch->cipherSuite.size;
|
||||||
@@ -659,13 +654,28 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch,
|
|||||||
TLSX_Remove(&parsedExts, TLSX_KEY_SHARE, ssl->heap);
|
TLSX_Remove(&parsedExts, TLSX_KEY_SHARE, ssl->heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is required to correctly generate the hash */
|
||||||
|
ret = SetCipherSpecs_ex(WOLFSSL_SERVER_END, cs.cipherSuite0,
|
||||||
|
cs.cipherSuite, &specs, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
goto dtls13_cleanup;
|
||||||
|
|
||||||
|
/* Calculate the cookie hash */
|
||||||
|
ret = Dtls13HashClientHello(ssl, cookieHash, &cookieHashSz, ch->raw,
|
||||||
|
ch->length, &specs);
|
||||||
|
if (ret != 0)
|
||||||
|
goto dtls13_cleanup;
|
||||||
|
|
||||||
|
/* Push the cookie to extensions */
|
||||||
|
ret = CreateCookieExt(ssl, cookieHash, cookieHashSz, &parsedExts,
|
||||||
|
cs.cipherSuite0, cs.cipherSuite);
|
||||||
|
if (ret != 0)
|
||||||
|
goto dtls13_cleanup;
|
||||||
|
|
||||||
{
|
{
|
||||||
WOLFSSL* nonConstSSL = (WOLFSSL*)ssl;
|
WOLFSSL* nonConstSSL = (WOLFSSL*)ssl;
|
||||||
TLSX* sslExts = nonConstSSL->extensions;
|
TLSX* sslExts = nonConstSSL->extensions;
|
||||||
|
|
||||||
/* This is required to correctly generate the hash */
|
|
||||||
ret = SetCipherSpecs_ex(WOLFSSL_SERVER_END, cs.cipherSuite0,
|
|
||||||
cs.cipherSuite, &nonConstSSL->specs, NULL);
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto dtls13_cleanup;
|
goto dtls13_cleanup;
|
||||||
nonConstSSL->options.tls = 1;
|
nonConstSSL->options.tls = 1;
|
||||||
@@ -684,8 +694,6 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch,
|
|||||||
/* Can be modified inside SendTls13ServerHello */
|
/* Can be modified inside SendTls13ServerHello */
|
||||||
parsedExts = nonConstSSL->extensions;
|
parsedExts = nonConstSSL->extensions;
|
||||||
|
|
||||||
InitCipherSpecs(&nonConstSSL->specs);
|
|
||||||
|
|
||||||
nonConstSSL->session->sessionIDSz = 0;
|
nonConstSSL->session->sessionIDSz = 0;
|
||||||
nonConstSSL->options.cipherSuite0 = 0;
|
nonConstSSL->options.cipherSuite0 = 0;
|
||||||
nonConstSSL->options.cipherSuite = 0;
|
nonConstSSL->options.cipherSuite = 0;
|
||||||
|
28
src/dtls13.c
28
src/dtls13.c
@@ -437,24 +437,36 @@ static int Dtls13SendNow(WOLFSSL* ssl, enum HandShakeType handshakeType)
|
|||||||
|
|
||||||
/* Handshake header DTLS only fields are not inlcuded in the transcript hash.
|
/* Handshake header DTLS only fields are not inlcuded in the transcript hash.
|
||||||
* body points to the body of the DTLSHandshake message. */
|
* body points to the body of the DTLSHandshake message. */
|
||||||
int Dtls13HashHandshakeType(WOLFSSL* ssl, const byte* body, word32 length,
|
int Dtls13HashClientHello(const WOLFSSL* ssl, byte* hash, int* hashSz,
|
||||||
enum HandShakeType handshakeType)
|
const byte* body, word32 length, CipherSpecs* specs)
|
||||||
{
|
{
|
||||||
/* msg_type(1) + length (3) */
|
/* msg_type(1) + length (3) */
|
||||||
byte header[OPAQUE32_LEN];
|
byte header[OPAQUE32_LEN];
|
||||||
int ret;
|
int ret;
|
||||||
|
wc_HashAlg hashCtx;
|
||||||
|
int type = wolfSSL_GetHmacType_ex(specs);
|
||||||
|
|
||||||
header[0] = (byte)handshakeType;
|
header[0] = (byte)client_hello;
|
||||||
c32to24(length, header + 1);
|
c32to24(length, header + 1);
|
||||||
|
|
||||||
ret = HashRaw(ssl, header, OPAQUE32_LEN);
|
ret = wc_HashInit_ex(&hashCtx, type, ssl->heap, ssl->devId);
|
||||||
if (ret != 0)
|
if (ret == 0) {
|
||||||
|
ret = wc_HashUpdate(&hashCtx, type, header, OPAQUE32_LEN);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_HashUpdate(&hashCtx, type, body, length);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_HashFinal(&hashCtx, type, hash);
|
||||||
|
if (ret == 0) {
|
||||||
|
*hashSz = wc_HashGetDigestSize(type);
|
||||||
|
if (*hashSz < 0)
|
||||||
|
ret = *hashSz;
|
||||||
|
}
|
||||||
|
wc_HashFree(&hashCtx, type);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return HashRaw(ssl, body, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handshake header DTLS only fields are not inlcuded in the transcript hash */
|
/* Handshake header DTLS only fields are not included in the transcript hash */
|
||||||
int Dtls13HashHandshake(WOLFSSL* ssl, const byte* input, word16 length)
|
int Dtls13HashHandshake(WOLFSSL* ssl, const byte* input, word16 length)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
17
src/tls.c
17
src/tls.c
@@ -663,14 +663,12 @@ int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wolfSSL_GetHmacType_ex(CipherSpecs* specs)
|
||||||
/* return HMAC digest type in wolfSSL format */
|
|
||||||
int wolfSSL_GetHmacType(WOLFSSL* ssl)
|
|
||||||
{
|
{
|
||||||
if (ssl == NULL)
|
if (specs == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
switch (ssl->specs.mac_algorithm) {
|
switch (specs->mac_algorithm) {
|
||||||
#ifndef NO_MD5
|
#ifndef NO_MD5
|
||||||
case md5_mac:
|
case md5_mac:
|
||||||
{
|
{
|
||||||
@@ -709,6 +707,15 @@ int wolfSSL_GetHmacType(WOLFSSL* ssl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return HMAC digest type in wolfSSL format */
|
||||||
|
int wolfSSL_GetHmacType(WOLFSSL* ssl)
|
||||||
|
{
|
||||||
|
if (ssl == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return wolfSSL_GetHmacType_ex(&ssl->specs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
|
int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
|
||||||
int verify)
|
int verify)
|
||||||
|
82
src/tls13.c
82
src/tls13.c
@@ -3337,14 +3337,34 @@ byte SuiteMac(const byte* suite)
|
|||||||
* hashSz The size of the hash data in bytes.
|
* hashSz The size of the hash data in bytes.
|
||||||
* returns 0 on success, otherwise failure.
|
* returns 0 on success, otherwise failure.
|
||||||
*/
|
*/
|
||||||
static int CreateCookieExt(const WOLFSSL* ssl, byte* hash, word16 hashSz,
|
int CreateCookieExt(const WOLFSSL* ssl, byte* hash, word16 hashSz,
|
||||||
TLSX** exts)
|
TLSX** exts, byte cipherSuite0, byte cipherSuite)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
byte mac[WC_MAX_DIGEST_SIZE] = {0};
|
byte mac[WC_MAX_DIGEST_SIZE] = {0};
|
||||||
Hmac cookieHmac;
|
Hmac cookieHmac;
|
||||||
byte cookieType = 0;
|
byte cookieType = 0;
|
||||||
byte macSz = 0;
|
byte macSz = 0;
|
||||||
|
byte cookie[OPAQUE8_LEN + WC_MAX_DIGEST_SIZE + OPAQUE16_LEN * 2];
|
||||||
|
TLSX* ext;
|
||||||
|
word16 cookieSz = 0;
|
||||||
|
|
||||||
|
/* Cookie Data = Hash Len | Hash | CS | KeyShare Group */
|
||||||
|
cookie[cookieSz++] = hashSz;
|
||||||
|
XMEMCPY(cookie + cookieSz, hash, hashSz);
|
||||||
|
cookieSz += hashSz;
|
||||||
|
cookie[cookieSz++] = cipherSuite0;
|
||||||
|
cookie[cookieSz++] = cipherSuite;
|
||||||
|
if ((ext = TLSX_Find(*exts, TLSX_KEY_SHARE)) != NULL) {
|
||||||
|
KeyShareEntry* kse = (KeyShareEntry*)ext->data;
|
||||||
|
if (kse == NULL) {
|
||||||
|
WOLFSSL_MSG("KeyShareEntry can't be empty when negotiating "
|
||||||
|
"parameters");
|
||||||
|
return BAD_STATE_E;
|
||||||
|
}
|
||||||
|
c16toa(kse->group, cookie + cookieSz);
|
||||||
|
cookieSz += OPAQUE16_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(NO_SHA) && defined(NO_SHA256)
|
#if !defined(NO_SHA) && defined(NO_SHA256)
|
||||||
cookieType = SHA;
|
cookieType = SHA;
|
||||||
@@ -3362,7 +3382,7 @@ static int CreateCookieExt(const WOLFSSL* ssl, byte* hash, word16 hashSz,
|
|||||||
ssl->buffers.tls13CookieSecret.length);
|
ssl->buffers.tls13CookieSecret.length);
|
||||||
}
|
}
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_HmacUpdate(&cookieHmac, hash, hashSz);
|
ret = wc_HmacUpdate(&cookieHmac, cookie, cookieSz);
|
||||||
#ifdef WOLFSSL_DTLS13
|
#ifdef WOLFSSL_DTLS13
|
||||||
/* Tie cookie to peer address */
|
/* Tie cookie to peer address */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@@ -3381,7 +3401,7 @@ static int CreateCookieExt(const WOLFSSL* ssl, byte* hash, word16 hashSz,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* The cookie data is the hash and the integrity check. */
|
/* The cookie data is the hash and the integrity check. */
|
||||||
return TLSX_Cookie_Use(ssl, hash, hashSz, mac, macSz, 1, exts);
|
return TLSX_Cookie_Use(ssl, cookie, cookieSz, mac, macSz, 1, exts);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3391,16 +3411,13 @@ static int CreateCookieExt(const WOLFSSL* ssl, byte* hash, word16 hashSz,
|
|||||||
#define HRR_MAX_HS_HEADER_SZ HANDSHAKE_HEADER_SZ
|
#define HRR_MAX_HS_HEADER_SZ HANDSHAKE_HEADER_SZ
|
||||||
#endif /* WOLFSSL_DTLS13 */
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
|
|
||||||
static int CreateCookieHash(const WOLFSSL* ssl, byte** hash, byte* hashSz,
|
static int CreateCookie(const WOLFSSL* ssl, byte** hash, byte* hashSz,
|
||||||
Hashes* hashes, TLSX** exts)
|
Hashes* hashes, TLSX** exts)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
(void)exts;
|
(void)exts;
|
||||||
|
|
||||||
ret = BuildCertHashes(ssl, hashes);
|
|
||||||
if (ret != 0)
|
|
||||||
return ret;
|
|
||||||
*hash = NULL;
|
*hash = NULL;
|
||||||
switch (ssl->specs.mac_algorithm) {
|
switch (ssl->specs.mac_algorithm) {
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
@@ -3426,30 +3443,9 @@ static int CreateCookieHash(const WOLFSSL* ssl, byte** hash, byte* hashSz,
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
|
#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
|
||||||
if (ssl->options.sendCookie && ssl->options.side == WOLFSSL_SERVER_END) {
|
if (ssl->options.sendCookie && ssl->options.side == WOLFSSL_SERVER_END)
|
||||||
byte cookie[OPAQUE8_LEN + WC_MAX_DIGEST_SIZE + OPAQUE16_LEN * 2];
|
ret = CreateCookieExt(ssl, *hash, *hashSz, exts,
|
||||||
TLSX* ext;
|
ssl->options.cipherSuite0, ssl->options.cipherSuite);
|
||||||
word16 idx = 0;
|
|
||||||
|
|
||||||
/* Cookie Data = Hash Len | Hash | CS | KeyShare Group */
|
|
||||||
cookie[idx++] = *hashSz;
|
|
||||||
if (*hash)
|
|
||||||
XMEMCPY(cookie + idx, *hash, *hashSz);
|
|
||||||
idx += *hashSz;
|
|
||||||
cookie[idx++] = ssl->options.cipherSuite0;
|
|
||||||
cookie[idx++] = ssl->options.cipherSuite;
|
|
||||||
if ((ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE)) != NULL) {
|
|
||||||
KeyShareEntry* kse = (KeyShareEntry*)ext->data;
|
|
||||||
if (kse == NULL) {
|
|
||||||
WOLFSSL_MSG("KeyShareEntry can't be empty when negotiating "
|
|
||||||
"parameters");
|
|
||||||
return BAD_STATE_E;
|
|
||||||
}
|
|
||||||
c16toa(kse->group, cookie + idx);
|
|
||||||
idx += OPAQUE16_LEN;
|
|
||||||
}
|
|
||||||
ret = CreateCookieExt(ssl, cookie, idx, exts);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -3467,7 +3463,10 @@ int RestartHandshakeHash(WOLFSSL* ssl)
|
|||||||
byte* hash = NULL;
|
byte* hash = NULL;
|
||||||
byte hashSz = 0;
|
byte hashSz = 0;
|
||||||
|
|
||||||
ret = CreateCookieHash(ssl, &hash, &hashSz, &hashes, &ssl->extensions);
|
ret = BuildCertHashes(ssl, &hashes);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = CreateCookie(ssl, &hash, &hashSz, &hashes, &ssl->extensions);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
|
#if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
|
||||||
@@ -6883,7 +6882,13 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
|
|||||||
WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
|
WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
|
||||||
WOLFSSL_ENTER("SendTls13ServerHello");
|
WOLFSSL_ENTER("SendTls13ServerHello");
|
||||||
|
|
||||||
if (extMsgType == hello_retry_request) {
|
/* When ssl->options.dtlsStateful is not set then cookie is calculated in
|
||||||
|
* dtls.c */
|
||||||
|
if (extMsgType == hello_retry_request
|
||||||
|
#ifdef WOLFSSL_DTLS13
|
||||||
|
&& (!ssl->options.dtls || ssl->options.dtlsStateful)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
WOLFSSL_MSG("wolfSSL Sending HelloRetryRequest");
|
WOLFSSL_MSG("wolfSSL Sending HelloRetryRequest");
|
||||||
if ((ret = RestartHandshakeHash(ssl)) < 0)
|
if ((ret = RestartHandshakeHash(ssl)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -6970,6 +6975,13 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
|
|||||||
if (ssl->options.sendCookie && extMsgType == hello_retry_request) {
|
if (ssl->options.sendCookie && extMsgType == hello_retry_request) {
|
||||||
/* Reset the hashes from here. We will be able to restart the hashes
|
/* Reset the hashes from here. We will be able to restart the hashes
|
||||||
* from the cookie in RestartHandshakeHashWithCookie */
|
* from the cookie in RestartHandshakeHashWithCookie */
|
||||||
|
#ifdef WOLFSSL_DTLS13
|
||||||
|
/* When ssl->options.dtlsStateful is not set then cookie is calculated
|
||||||
|
* in dtls.c */
|
||||||
|
if (ssl->options.dtls && !ssl->options.dtlsStateful)
|
||||||
|
ret = 0;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
ret = InitHandshakeHashes(ssl);
|
ret = InitHandshakeHashes(ssl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -5863,6 +5863,10 @@ WOLFSSL_LOCAL int cipherExtraData(WOLFSSL* ssl);
|
|||||||
WOLFSSL_LOCAL int SendHelloVerifyRequest(WOLFSSL* ssl,
|
WOLFSSL_LOCAL int SendHelloVerifyRequest(WOLFSSL* ssl,
|
||||||
const byte* cookie, byte cookieSz);
|
const byte* cookie, byte cookieSz);
|
||||||
|
|
||||||
|
WOLFSSL_LOCAL int CreateCookieExt(const WOLFSSL* ssl, byte* hash,
|
||||||
|
word16 hashSz, TLSX** exts,
|
||||||
|
byte cipherSuite0, byte cipherSuite);
|
||||||
|
|
||||||
#if !defined(NO_WOLFSSL_SERVER)
|
#if !defined(NO_WOLFSSL_SERVER)
|
||||||
WOLFSSL_LOCAL int DoClientHelloStateless(WOLFSSL* ssl,
|
WOLFSSL_LOCAL int DoClientHelloStateless(WOLFSSL* ssl,
|
||||||
const byte* input, word32* inOutIdx, word32 helloSz);
|
const byte* input, word32* inOutIdx, word32 helloSz);
|
||||||
@@ -6128,8 +6132,8 @@ WOLFSSL_LOCAL int Dtls13RtxProcessingCertificate(WOLFSSL* ssl, byte* input,
|
|||||||
word32 inputSize);
|
word32 inputSize);
|
||||||
WOLFSSL_LOCAL int Dtls13HashHandshake(WOLFSSL* ssl, const byte* input,
|
WOLFSSL_LOCAL int Dtls13HashHandshake(WOLFSSL* ssl, const byte* input,
|
||||||
word16 length);
|
word16 length);
|
||||||
WOLFSSL_LOCAL int Dtls13HashHandshakeType(WOLFSSL* ssl, const byte* body,
|
WOLFSSL_LOCAL int Dtls13HashClientHello(const WOLFSSL* ssl, byte* hash,
|
||||||
word32 length, enum HandShakeType handshakeType);
|
int* hashSz, const byte* body, word32 length, CipherSpecs* specs);
|
||||||
WOLFSSL_LOCAL void Dtls13FreeFsmResources(WOLFSSL* ssl);
|
WOLFSSL_LOCAL void Dtls13FreeFsmResources(WOLFSSL* ssl);
|
||||||
WOLFSSL_LOCAL int Dtls13RtxTimeout(WOLFSSL* ssl);
|
WOLFSSL_LOCAL int Dtls13RtxTimeout(WOLFSSL* ssl);
|
||||||
WOLFSSL_LOCAL int Dtls13ProcessBufferedMessages(WOLFSSL* ssl);
|
WOLFSSL_LOCAL int Dtls13ProcessBufferedMessages(WOLFSSL* ssl);
|
||||||
@@ -6218,6 +6222,8 @@ WOLFSSL_LOCAL int FindPskSuite(const WOLFSSL* ssl, PreSharedKey* psk,
|
|||||||
byte* foundSuite);
|
byte* foundSuite);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
WOLFSSL_LOCAL int wolfSSL_GetHmacType_ex(CipherSpecs* specs);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user