SSL session ticket: decrypted ticket access aligned

Decrypted session ticket using encrypted ticket buffer.
Alignment not correct on platforms requiring 32-bit aligned access.
Copy the decrypted data into temporary for access.
Also zeroize the unencrypted tickets after use.
This commit is contained in:
Sean Parkinson
2020-10-08 08:56:49 +10:00
parent 84ee1509b7
commit 8d82fb2add

View File

@ -28223,22 +28223,27 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif #endif
} }
/* build external */
XMEMCPY(et->enc_ticket, &it, sizeof(InternalTicket));
/* encrypt */ /* encrypt */
encLen = WOLFSSL_TICKET_ENC_SZ; /* max size user can use */ encLen = WOLFSSL_TICKET_ENC_SZ; /* max size user can use */
if (ssl->ctx->ticketEncCb == NULL) { if (ssl->ctx->ticketEncCb == NULL) {
ret = WOLFSSL_TICKET_RET_FATAL; ret = WOLFSSL_TICKET_RET_FATAL;
} }
else { else {
/* build external */
XMEMCPY(et->enc_ticket, &it, sizeof(InternalTicket));
ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac, 1, ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac, 1,
et->enc_ticket, sizeof(InternalTicket), et->enc_ticket, sizeof(InternalTicket),
&encLen, ssl->ctx->ticketEncCtx); &encLen, ssl->ctx->ticketEncCtx);
if (ret != WOLFSSL_TICKET_RET_OK) {
ForceZero(et->enc_ticket, sizeof(it));
}
} }
if (ret == WOLFSSL_TICKET_RET_OK) { if (ret == WOLFSSL_TICKET_RET_OK) {
if (encLen < (int)sizeof(InternalTicket) || if (encLen < (int)sizeof(InternalTicket) ||
encLen > WOLFSSL_TICKET_ENC_SZ) { encLen > WOLFSSL_TICKET_ENC_SZ) {
ForceZero(&it, sizeof(it));
ForceZero(et->enc_ticket, sizeof(it));
WOLFSSL_MSG("Bad user ticket encrypt size"); WOLFSSL_MSG("Bad user ticket encrypt size");
return BAD_TICKET_KEY_CB_SZ; return BAD_TICKET_KEY_CB_SZ;
} }
@ -28247,10 +28252,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* internal ticket can't be the same if encrypted */ /* internal ticket can't be the same if encrypted */
if (XMEMCMP(et->enc_ticket, &it, sizeof(InternalTicket)) == 0) { if (XMEMCMP(et->enc_ticket, &it, sizeof(InternalTicket)) == 0) {
ForceZero(&it, sizeof(it));
ForceZero(et->enc_ticket, sizeof(it));
WOLFSSL_MSG("User ticket encrypt didn't encrypt"); WOLFSSL_MSG("User ticket encrypt didn't encrypt");
return BAD_TICKET_ENCRYPT; return BAD_TICKET_ENCRYPT;
} }
ForceZero(&it, sizeof(it));
XMEMSET(zeros, 0, sizeof(zeros)); XMEMSET(zeros, 0, sizeof(zeros));
/* name */ /* name */
@ -28288,7 +28296,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len) int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
{ {
ExternalTicket* et; ExternalTicket* et;
InternalTicket* it; InternalTicket it;
int ret; int ret;
int outLen; int outLen;
word16 inLen; word16 inLen;
@ -28302,7 +28310,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
} }
et = (ExternalTicket*)input; et = (ExternalTicket*)input;
it = (InternalTicket*)et->enc_ticket;
/* decrypt */ /* decrypt */
ato16(et->enc_len, &inLen); ato16(et->enc_len, &inLen);
@ -28326,55 +28333,65 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
return BAD_TICKET_KEY_CB_SZ; return BAD_TICKET_KEY_CB_SZ;
} }
/* copy the decrypted ticket to avoid alignment issues */
XMEMCPY(&it, et->enc_ticket, sizeof(InternalTicket));
ForceZero(et->enc_ticket, sizeof(it));
/* get master secret */ /* get master secret */
if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE) { if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE) {
if (ssl->version.minor < it->pv.minor) { if (ssl->version.minor < it.pv.minor) {
ForceZero(&it, sizeof(it));
WOLFSSL_MSG("Ticket has greater version"); WOLFSSL_MSG("Ticket has greater version");
return VERSION_ERROR; return VERSION_ERROR;
} }
else if (ssl->version.minor > it->pv.minor) { else if (ssl->version.minor > it.pv.minor) {
if (!ssl->options.downgrade) { if (!ssl->options.downgrade) {
ForceZero(&it, sizeof(it));
WOLFSSL_MSG("Ticket has lesser version"); WOLFSSL_MSG("Ticket has lesser version");
return VERSION_ERROR; return VERSION_ERROR;
} }
WOLFSSL_MSG("Downgrading protocol due to ticket"); WOLFSSL_MSG("Downgrading protocol due to ticket");
if (it->pv.minor < ssl->options.minDowngrade) if (it.pv.minor < ssl->options.minDowngrade) {
ForceZero(&it, sizeof(it));
return VERSION_ERROR; return VERSION_ERROR;
ssl->version.minor = it->pv.minor; }
ssl->version.minor = it.pv.minor;
} }
if (!IsAtLeastTLSv1_3(ssl->version)) { if (!IsAtLeastTLSv1_3(ssl->version)) {
XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN); XMEMCPY(ssl->arrays->masterSecret, it.msecret, SECRET_LEN);
/* Copy the haveExtendedMasterSecret property from the ticket to /* Copy the haveExtendedMasterSecret property from the ticket to
* the saved session, so the property may be checked later. */ * the saved session, so the property may be checked later. */
ssl->session.haveEMS = it->haveEMS; ssl->session.haveEMS = it.haveEMS;
#ifndef NO_RESUME_SUITE_CHECK #ifndef NO_RESUME_SUITE_CHECK
ssl->session.cipherSuite0 = it->suite[0]; ssl->session.cipherSuite0 = it.suite[0];
ssl->session.cipherSuite = it->suite[1]; ssl->session.cipherSuite = it.suite[1];
#endif #endif
} }
else { else {
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
/* Restore information to renegotiate. */ /* Restore information to renegotiate. */
ssl->session.ticketSeen = it->timestamp; ssl->session.ticketSeen = it.timestamp;
ssl->session.ticketAdd = it->ageAdd; ssl->session.ticketAdd = it.ageAdd;
ssl->session.cipherSuite0 = it->suite[0]; ssl->session.cipherSuite0 = it.suite[0];
ssl->session.cipherSuite = it->suite[1]; ssl->session.cipherSuite = it.suite[1];
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
ssl->session.maxEarlyDataSz = it->maxEarlyDataSz; ssl->session.maxEarlyDataSz = it.maxEarlyDataSz;
#endif #endif
/* Resumption master secret. */ /* Resumption master secret. */
XMEMCPY(ssl->session.masterSecret, it->msecret, SECRET_LEN); XMEMCPY(ssl->session.masterSecret, it.msecret, SECRET_LEN);
XMEMCPY(&ssl->session.ticketNonce, &it->ticketNonce, XMEMCPY(&ssl->session.ticketNonce, &it.ticketNonce,
sizeof(TicketNonce)); sizeof(TicketNonce));
ssl->session.namedGroup = it->namedGroup; ssl->session.namedGroup = it.namedGroup;
#endif #endif
} }
} }
ForceZero(&it, sizeof(it));
WOLFSSL_LEAVE("DoClientTicket", ret); WOLFSSL_LEAVE("DoClientTicket", ret);
WOLFSSL_END(WC_FUNC_TICKET_DO); WOLFSSL_END(WC_FUNC_TICKET_DO);