Skip to content

Commit

Permalink
Default session ticket enc/dec: allow AES-CBC with HMAC
Browse files Browse the repository at this point in the history
Add option to use AES-CBC with HMAC for default session ticket enc/dec.
Defaults to AES-128-CBC with HMAC-SHA256.
Options include:
  WOLFSSL_TICKET_ENC_HMAC_SHA512 for HMAC-SHA512
  WOLFSSL_TICKET_ENC_HMAC_SHA384 for HMAC-SHA384
  WOLFSSL_TICKET_ENC_AES256_CBC for AES-256-CBC
  • Loading branch information
SparkiDev committed Jul 2, 2024
1 parent 3206637 commit c820815
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 8 deletions.
129 changes: 123 additions & 6 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -37718,7 +37718,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
itHash = HashObject((byte*)it, sizeof(*it), &error);
if (error == 0) {
ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac,
1, et->enc_ticket, sizeof(InternalTicket), &encLen,
1, et->enc_ticket, WOLFSSL_INTERNAL_TICKET_LEN, &encLen,
SSL_TICKET_CTX(ssl));
}
else {
Expand All @@ -37733,7 +37733,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif
goto error;
}
if (encLen < (int)sizeof(InternalTicket) ||
if (encLen < (int)WOLFSSL_INTERNAL_TICKET_LEN ||
encLen > (int)WOLFSSL_TICKET_ENC_SZ) {
WOLFSSL_MSG("Bad user ticket encrypt size");
ret = BAD_TICKET_KEY_CB_SZ;
Expand Down Expand Up @@ -37809,7 +37809,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_ENTER("DoDecryptTicket");

if (len > SESSION_TICKET_LEN ||
len < (word32)(sizeof(InternalTicket) + WOLFSSL_TICKET_FIXED_SZ)) {
len < (word32)(WOLFSSL_INTERNAL_TICKET_LEN +
WOLFSSL_TICKET_FIXED_SZ)) {
WOLFSSL_ERROR_VERBOSE(BAD_TICKET_MSG_SZ);
return WOLFSSL_TICKET_RET_REJECT;
}
Expand Down Expand Up @@ -37857,7 +37858,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
return WOLFSSL_TICKET_RET_REJECT;
}
}
if (outLen > (int)inLen || outLen < (int)sizeof(InternalTicket)) {
if (outLen > (int)inLen || outLen < (int)WOLFSSL_INTERNAL_TICKET_LEN) {
WOLFSSL_MSG("Bad user ticket decrypt len");
WOLFSSL_ERROR_VERBOSE(BAD_TICKET_KEY_CB_SZ);
return BAD_TICKET_KEY_CB_SZ;
Expand Down Expand Up @@ -38551,7 +38552,123 @@ static void TicketEncCbCtx_Free(TicketEncCbCtx* keyCtx)
wc_FreeRng(&keyCtx->rng);
}

#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \
#ifdef WOLFSSL_TICKET_ENC_CBC_HMAC
/* Ticket encryption/decryption implementation.
*
* @param [in] key Key for encryption/decryption and HMAC.
* @param [in] keyLen Length of key in bytes.
* @param [in] iv IV/Nonce for encryption/decryption.
* @param [in] aad Additional authentication data.
* @param [in] aadSz Length of additional authentication data.
* @param [in] in Data to encrypt/decrypt.
* @param [in] inLen Length of encrypted data.
* @param [out] out Resulting data from encrypt/decrypt.
* @param [out] outLen Size of resulting data.
* @param [in] tag Authentication tag for encrypted data.
* @param [in] heap Dynamic memory allocation data hint.
* @param [in] enc 1 when encrypting, 0 when decrypting.
* @return 0 on success.
* @return Other value when encryption/decryption fails.
*/
static int TicketEncDec(byte* key, int keyLen, byte* iv, byte* aad, int aadSz,
byte* in, int inLen, byte* out, int* outLen, byte* tag,
void* heap, int enc)
{
int ret;
#ifdef WOLFSSL_SMALL_STACK
Aes* aes;
Hmac* hmac;
#else
Aes aes[1];
Hmac hmac[1];
#endif

(void)heap;

#ifdef WOLFSSL_SMALL_STACK
aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_TMP_BUFFER);
if (aes == NULL)
return MEMORY_E;
hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_TMP_BUFFER);
if (hmac == NULL) {
XFREE(aes, heap, DYNAMIC_TYPE_TMP_BUFFER);
return MEMORY_E;
}
#endif

XMEMSET(aes, 0, sizeof(Aes));
XMEMSET(hmac, 0, sizeof(Hmac));

ret = wc_HmacInit(hmac, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (ret == 0) {
ret = wc_HmacSetKey(hmac, WOLFSSL_TICKET_ENC_HMAC, key + keyLen -
WOLFSSL_TICKET_HMAC_KEY_SZ, WOLFSSL_TICKET_HMAC_KEY_SZ);
}
if (ret == 0) {
ret = wc_HmacUpdate(hmac, aad, aadSz);
}

if (ret == 0) {
if (enc) {
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_AesSetKey(aes, key,
keyLen - WOLFSSL_TICKET_HMAC_KEY_SZ, iv, AES_ENCRYPTION);
}
if (ret == 0) {
ret = wc_HmacUpdate(hmac, in, inLen);
}
if (ret == 0) {
ret = wc_AesCbcEncrypt(aes, in, out, inLen);
}
if (ret == 0) {
XMEMSET(tag, 0, WOLFSSL_TICKET_MAC_SZ);
ret = wc_HmacFinal(hmac, tag);
}
wc_AesFree(aes);
}
else {
unsigned char calcTag[WOLFSSL_TICKET_MAC_SZ];

ret = wc_AesInit(aes, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_AesSetKey(aes, key,
keyLen - WOLFSSL_TICKET_HMAC_KEY_SZ, iv, AES_DECRYPTION);
}
if (ret == 0) {
ret = wc_AesCbcDecrypt(aes, in, out, inLen);
}
if (ret == 0) {
ret = wc_HmacUpdate(hmac, out, inLen);
}
if (ret == 0) {
XMEMSET(calcTag, 0, WOLFSSL_TICKET_MAC_SZ);
ret = wc_HmacFinal(hmac, calcTag);
}
if (ret == 0) {
int i;
calcTag[0] ^= tag[0];
for (i = 1; i < WOLFSSL_TICKET_MAC_SZ; i++) {
calcTag[0] |= calcTag[i] ^ tag[i];
}
/* Return a negative value when no match. */
ret = -calcTag[0];
}
wc_AesFree(aes);
}
}
wc_HmacFree(hmac);

#ifdef WOLFSSL_SMALL_STACK
XFREE(hmac, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(aes, heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif

*outLen = inLen;

return ret;
}
#elif defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \
!defined(WOLFSSL_TICKET_ENC_AES128_GCM) && \
!defined(WOLFSSL_TICKET_ENC_AES256_GCM)
/* Ticket encryption/decryption implementation.
Expand Down Expand Up @@ -38846,7 +38963,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],

WOLFSSL_ENTER("DefTicketEncCb");

if ((!enc) && (inLen != sizeof(InternalTicket))) {
if ((!enc) && (inLen != WOLFSSL_INTERNAL_TICKET_LEN)) {
return BUFFER_E;
}

Expand Down
7 changes: 7 additions & 0 deletions wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -3328,6 +3328,13 @@ typedef struct InternalTicket {
#endif /* OPENSSL_EXTRA */
} InternalTicket;

#ifndef WOLFSSL_TICKET_ENC_CBC_HMAC
#define WOLFSSL_INTERNAL_TICKET_LEN sizeof(InternalTicket)
#else
#define WOLFSSL_INTERNAL_TICKET_LEN \
(((sizeof(InternalTicket) + 15) / 16) * 16)
#endif

#ifndef WOLFSSL_TICKET_EXTRA_PADDING_SZ
#define WOLFSSL_TICKET_EXTRA_PADDING_SZ 32
#endif
Expand Down
26 changes: 24 additions & 2 deletions wolfssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4140,7 +4140,25 @@ WOLFSSL_API long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl);
#ifdef HAVE_SESSION_TICKET

#if !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && !defined(NO_WOLFSSL_SERVER)
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \
#ifdef WOLFSSL_TICKET_ENC_CBC_HMAC
#if defined(WOLFSSL_TICKET_ENC_HMAC_SHA512)
#define WOLFSSL_TICKET_ENC_HMAC WC_HASH_TYPE_SHA512
#define WOLFSSL_TICKET_HMAC_KEY_SZ 64
#elif defined(WOLFSSL_TICKET_ENC_HMAC_SHA384)
#define WOLFSSL_TICKET_ENC_HMAC WC_HASH_TYPE_SHA384
#define WOLFSSL_TICKET_HMAC_KEY_SZ 48
#else
#define WOLFSSL_TICKET_ENC_HMAC WC_HASH_TYPE_SHA256
#define WOLFSSL_TICKET_HMAC_KEY_SZ 32
#endif
#ifdef WOLFSSL_TICKET_ENC_AES256_CBC
#define WOLFSSL_TICKET_KEY_SZ \
(AES_256_KEY_SIZE + WOLFSSL_TICKET_HMAC_KEY_SZ)
#else
#define WOLFSSL_TICKET_KEY_SZ \
(AES_128_KEY_SIZE + WOLFSSL_TICKET_HMAC_KEY_SZ)
#endif
#elif defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \
!defined(WOLFSSL_TICKET_ENC_AES128_GCM) && \
!defined(WOLFSSL_TICKET_ENC_AES256_GCM)
#define WOLFSSL_TICKET_KEY_SZ CHACHA20_POLY1305_AEAD_KEYSIZE
Expand Down Expand Up @@ -4171,7 +4189,11 @@ WOLFSSL_API int wolfSSL_send_SessionTicket(WOLFSSL* ssl);

#define WOLFSSL_TICKET_NAME_SZ 16
#define WOLFSSL_TICKET_IV_SZ 16
#define WOLFSSL_TICKET_MAC_SZ 32
#ifndef WOLFSSL_TICKET_ENC_CBC_HMAC
#define WOLFSSL_TICKET_MAC_SZ 32
#else
#define WOLFSSL_TICKET_MAC_SZ WOLFSSL_TICKET_HMAC_KEY_SZ
#endif

enum TicketEncRet {
WOLFSSL_TICKET_RET_FATAL = -1, /* fatal error, don't use ticket */
Expand Down

0 comments on commit c820815

Please sign in to comment.