Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 54 additions & 42 deletions src/ssl_ech.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@
/* create the hpke key and ech config to send to clients */
int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName,
word16 kemId, word16 kdfId, word16 aeadId)
{
return wolfSSL_CTX_GenerateEchConfigEx(ctx, publicName, kemId, kdfId,
aeadId, 0);
}

/* create the hpke key and ech config to send to clients
* maximum_name_length may also be set for a more stable padding length */
int wolfSSL_CTX_GenerateEchConfigEx(WOLFSSL_CTX* ctx, const char* publicName,
word16 kemId, word16 kdfId, word16 aeadId, byte maxNameLen)
{
int ret = 0;
WOLFSSL_EchConfig* newConfig;
Expand Down Expand Up @@ -129,8 +138,8 @@ int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName,
ret = MEMORY_E;
}
else {
XMEMCPY(newConfig->publicName, publicName,
XSTRLEN(publicName) + 1);
XMEMCPY(newConfig->publicName, publicName, XSTRLEN(publicName) + 1);
newConfig->maxNameLen = maxNameLen;
}
}

Expand Down Expand Up @@ -166,33 +175,52 @@ int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName,
return ret;
}

int wolfSSL_CTX_SetEchConfigsBase64(WOLFSSL_CTX* ctx, const char* echConfigs64,
word32 echConfigs64Len)
/* base64-decode echConfigs into a freshly allocated buffer */
static int DecodeEchConfigsBase64(void* heap, const char* echConfigs64,
word32 echConfigs64Len, byte** decodedConfigs, word32* decodedLen)
{
int ret = 0;
word32 decodedLen = echConfigs64Len * 3 / 4 + 1;
byte* decodedConfigs;
byte* buf;
word32 len = echConfigs64Len * 3 / 4 + 1;

if (ctx == NULL || echConfigs64 == NULL || echConfigs64Len == 0)
if (echConfigs64 == NULL || echConfigs64Len == 0)
return BAD_FUNC_ARG;

decodedConfigs = (byte*)XMALLOC(decodedLen, ctx->heap,
DYNAMIC_TYPE_TMP_BUFFER);
buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER);

if (decodedConfigs == NULL)
if (buf == NULL)
return MEMORY_E;

decodedConfigs[decodedLen - 1] = 0;
buf[len - 1] = 0;

/* decode the echConfigs */
ret = Base64_Decode((const byte*)echConfigs64, echConfigs64Len,
decodedConfigs, &decodedLen);
ret = Base64_Decode((const byte*)echConfigs64, echConfigs64Len, buf, &len);

if (ret != 0) {
XFREE(decodedConfigs, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}

*decodedConfigs = buf;
*decodedLen = len;
return 0;
}

int wolfSSL_CTX_SetEchConfigsBase64(WOLFSSL_CTX* ctx, const char* echConfigs64,
word32 echConfigs64Len)
{
int ret;
word32 decodedLen;
byte* decodedConfigs;

if (ctx == NULL)
return BAD_FUNC_ARG;

ret = DecodeEchConfigsBase64(ctx->heap, echConfigs64, echConfigs64Len,
&decodedConfigs, &decodedLen);
if (ret != 0)
return ret;

ret = wolfSSL_CTX_SetEchConfigs(ctx, decodedConfigs, decodedLen);

XFREE(decodedConfigs, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
Expand Down Expand Up @@ -249,34 +277,17 @@ void wolfSSL_CTX_SetEchEnable(WOLFSSL_CTX* ctx, byte enable)
int wolfSSL_SetEchConfigsBase64(WOLFSSL* ssl, const char* echConfigs64,
word32 echConfigs64Len)
{
int ret = 0;
word32 decodedLen = echConfigs64Len * 3 / 4 + 1;
int ret;
word32 decodedLen;
byte* decodedConfigs;

if (ssl == NULL || echConfigs64 == NULL || echConfigs64Len == 0)
if (ssl == NULL)
return BAD_FUNC_ARG;

/* already have ech configs */
if (ssl->echConfigs != NULL) {
return WOLFSSL_FATAL_ERROR;
}

decodedConfigs = (byte*)XMALLOC(decodedLen, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);

if (decodedConfigs == NULL)
return MEMORY_E;

decodedConfigs[decodedLen - 1] = 0;

/* decode the echConfigs */
ret = Base64_Decode((const byte*)echConfigs64, echConfigs64Len,
decodedConfigs, &decodedLen);

if (ret != 0) {
XFREE(decodedConfigs, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
ret = DecodeEchConfigsBase64(ssl->heap, echConfigs64, echConfigs64Len,
&decodedConfigs, &decodedLen);
if (ret != 0)
return ret;
}

ret = wolfSSL_SetEchConfigs(ssl, decodedConfigs, decodedLen);

Expand Down Expand Up @@ -418,8 +429,8 @@ int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen)
output += 2;
}

/* set maximum name length to 0 */
*output = 0;
/* maximum name len */
*output = config->maxNameLen;
output++;

/* publicName len */
Expand All @@ -430,7 +441,7 @@ int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen)
XMEMCPY(output, config->publicName, publicNameLen);
output += publicNameLen;

/* terminating zeros */
/* no extensions, print zeros */
c16toa(0, output);
/* output += 2; */

Expand Down Expand Up @@ -656,11 +667,12 @@ int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap,
idx += 4;
}

/* ignore maximum name length */
/* maxNameLen */
if (idx + 1 > length) {
ret = BUFFER_E;
break;
}
workingConfig->maxNameLen = echConfig[idx];
idx += 1;

/* publicName */
Expand Down Expand Up @@ -701,7 +713,7 @@ int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap,
}

ret = EchConfigCheckExtensions(echConfig + idx, extensionsLen);
if (ret < 0)
if (ret < 0 && ret != WC_NO_ERR_TRACE(UNSUPPORTED_EXTENSION))
break;

/* KEM, ciphersuite, or mandatory extension not supported, free this
Expand Down
16 changes: 15 additions & 1 deletion src/tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -4817,9 +4817,23 @@ int SendTls13ClientHello(WOLFSSL* ssl)
if (ret != 0)
return ret;

/* calculate padding (RFC 9849, section 6.1.3) */
if (args->ech->privateName != NULL) {
word16 nameLen = (word16)XSTRLEN(args->ech->privateName);
if (nameLen > args->ech->echConfig->maxNameLen)
args->ech->paddingLen = 0;
else
args->ech->paddingLen =
(word16)args->ech->echConfig->maxNameLen - nameLen;
}
else {
args->ech->paddingLen = args->ech->echConfig->maxNameLen + 9;
}

/* innerClientHelloLen and padding are based on the
* encoded (sealed) inner */
args->ech->paddingLen = 31 - ((encodedLen - 1) % 32);
args->ech->paddingLen += 31 -
((encodedLen + args->ech->paddingLen - 1) % 32);
args->ech->innerClientHelloLen = encodedLen +
args->ech->paddingLen + args->ech->hpke->Nt;

Expand Down
6 changes: 4 additions & 2 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -15066,8 +15066,10 @@ static int test_ech_server_ctx_ready(WOLFSSL_CTX* ctx)
{
int ret;

ret = wolfSSL_CTX_GenerateEchConfig(ctx, echCbTestPublicName,
echCbTestKemID, echCbTestKdfID, echCbTestAeadID);
/* +20 for this isn't significant, it just exercises the padding code */
ret = wolfSSL_CTX_GenerateEchConfigEx(ctx, echCbTestPublicName,
echCbTestKemID, echCbTestKdfID, echCbTestAeadID,
XSTRLEN(echCbTestPublicName) + 20);
if (ret != WOLFSSL_SUCCESS)
return TEST_FAIL;

Expand Down
1 change: 1 addition & 0 deletions wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -3147,6 +3147,7 @@ typedef struct WOLFSSL_EchConfig {
byte configId;
byte numCipherSuites;
byte receiverPubkey[HPKE_Npk_MAX];
byte maxNameLen;
Comment thread
dgarske marked this conversation as resolved.
} WOLFSSL_EchConfig;

typedef struct WOLFSSL_ECH {
Expand Down
3 changes: 3 additions & 0 deletions wolfssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,9 @@ WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_method(void);
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
WOLFSSL_API int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx,
const char* publicName, word16 kemId, word16 kdfId, word16 aeadId);
WOLFSSL_API int wolfSSL_CTX_GenerateEchConfigEx(WOLFSSL_CTX* ctx,
const char* publicName, word16 kemId, word16 kdfId, word16 aeadId,
byte maxNameLen);

WOLFSSL_API int wolfSSL_CTX_SetEchConfigsBase64(WOLFSSL_CTX* ctx,
const char* echConfigs64, word32 echConfigs64Len);
Expand Down
Loading