forked from wolfSSL/wolfssl
truncated hmac export and sanity checks
This commit is contained in:
298
src/internal.c
298
src/internal.c
@@ -357,16 +357,17 @@ static INLINE void c32toa(word32 u32, byte* c)
|
|||||||
c[3] = u32 & 0xff;
|
c[3] = u32 & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void cw64toa(word64 u64, byte* c)
|
/* convert 64 bit integer to opaque */
|
||||||
|
static INLINE void c64toa(word64 u64, byte* c)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
c[0] = (u64 >> 56) & 0xff;
|
||||||
int idx = OPAQUE64_LEN - 1;
|
c[1] = (u64 >> 48) & 0xff;
|
||||||
|
c[2] = (u64 >> 40) & 0xff;
|
||||||
XMEMSET(c, 0, OPAQUE64_LEN);
|
c[3] = (u64 >> 32) & 0xff;
|
||||||
|
c[4] = (u64 >> 24) & 0xff;
|
||||||
for (i = 0; i < sizeof(word64) && idx >= 0; i++) {
|
c[5] = (u64 >> 16) & 0xff;
|
||||||
c[idx--] = (u64 >> (i * WOLFSSL_BIT_SIZE)) & 0xff;
|
c[6] = (u64 >> 8) & 0xff;
|
||||||
}
|
c[7] = u64 & 0xff;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -395,14 +396,17 @@ static INLINE void ato32(const byte* c, word32* u32)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* convert opaque to word64 type */
|
/* convert opaque to word64 type */
|
||||||
static INLINE void atow64(const byte* c, word64* u64)
|
static INLINE void ato64(const byte* c, word64* u64)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
/* when doing cast to allow for shift, mask the values */
|
||||||
int idx = sizeof(word64);
|
*u64 = (((word64)c[0] << 56) & 0xff00000000000000) |
|
||||||
|
(((word64)c[1] << 48) & 0x00ff000000000000) |
|
||||||
for (i = 0; i < sizeof(word64) && idx >= 0; i++) {
|
(((word64)c[2] << 40) & 0x0000ff0000000000) |
|
||||||
*u64 |= ((word64)c[idx--] << (i * WOLFSSL_BIT_SIZE));
|
(((word64)c[3] << 32) & 0x000000ff00000000) |
|
||||||
}
|
(((word64)c[4] << 24) & 0x00000000ff000000) |
|
||||||
|
(((word64)c[5] << 16) & 0x0000000000ff0000) |
|
||||||
|
(((word64)c[6] << 8) & 0x000000000000ff00) |
|
||||||
|
((word64)c[7] & 0x00000000000000ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WOLFSSL_DTLS */
|
#endif /* WOLFSSL_DTLS */
|
||||||
@@ -502,6 +506,8 @@ static int ExportCipherSpecState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
CipherSpecs* specs;
|
CipherSpecs* specs;
|
||||||
|
|
||||||
|
WOLFSSL_ENTER("ExportCipherSpecState");
|
||||||
|
|
||||||
if (exp == NULL || ssl == NULL) {
|
if (exp == NULL || ssl == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
@@ -512,6 +518,8 @@ static int ExportCipherSpecState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMEMSET(exp, 0, DTLS_EXPORT_SPC_SZ);
|
||||||
|
|
||||||
c16toa(specs->key_size, exp + idx); idx += OPAQUE16_LEN;
|
c16toa(specs->key_size, exp + idx); idx += OPAQUE16_LEN;
|
||||||
c16toa(specs->iv_size, exp + idx); idx += OPAQUE16_LEN;
|
c16toa(specs->iv_size, exp + idx); idx += OPAQUE16_LEN;
|
||||||
c16toa(specs->block_size, exp + idx); idx += OPAQUE16_LEN;
|
c16toa(specs->block_size, exp + idx); idx += OPAQUE16_LEN;
|
||||||
@@ -527,11 +535,12 @@ static int ExportCipherSpecState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
|
|
||||||
if (idx != DTLS_EXPORT_SPC_SZ) {
|
if (idx != DTLS_EXPORT_SPC_SZ) {
|
||||||
WOLFSSL_MSG("DTLS_EXPORT_SPC_SZ needs updated and export version");
|
WOLFSSL_MSG("DTLS_EXPORT_SPC_SZ needs updated and export version");
|
||||||
return BUFFER_E;
|
return DTLS_EXPORT_VER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WOLFSSL_LEAVE("ExportCipherSpecState", idx);
|
||||||
(void)ver;
|
(void)ver;
|
||||||
return 0;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -539,8 +548,11 @@ static int ExportCipherSpecState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
static int ExportKeyState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
static int ExportKeyState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
|
byte sz;
|
||||||
Keys* keys;
|
Keys* keys;
|
||||||
|
|
||||||
|
WOLFSSL_ENTER("ExportKeyState");
|
||||||
|
|
||||||
if (exp == NULL || ssl == NULL) {
|
if (exp == NULL || ssl == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
@@ -551,24 +563,7 @@ static int ExportKeyState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(exp + idx, keys->client_write_MAC_secret, MAX_DIGEST_SIZE);
|
XMEMSET(exp, 0, DTLS_EXPORT_KEY_SZ);
|
||||||
idx += MAX_DIGEST_SIZE; /* largest digest size */
|
|
||||||
XMEMCPY(exp + idx, keys->server_write_MAC_secret, MAX_DIGEST_SIZE);
|
|
||||||
idx += MAX_DIGEST_SIZE; /* largest digest size */
|
|
||||||
XMEMCPY(exp + idx, keys->client_write_key, AES_256_KEY_SIZE);
|
|
||||||
idx += AES_256_KEY_SIZE;
|
|
||||||
XMEMCPY(exp + idx, keys->server_write_key, AES_256_KEY_SIZE);
|
|
||||||
idx += AES_256_KEY_SIZE;
|
|
||||||
XMEMCPY(exp + idx, keys->client_write_IV, MAX_WRITE_IV_SZ);
|
|
||||||
idx += MAX_WRITE_IV_SZ;
|
|
||||||
XMEMCPY(exp + idx, keys->server_write_IV, MAX_WRITE_IV_SZ);
|
|
||||||
idx += MAX_WRITE_IV_SZ;
|
|
||||||
XMEMCPY(exp + idx, keys->aead_exp_IV, AEAD_MAX_EXP_SZ);
|
|
||||||
idx += AEAD_MAX_EXP_SZ;
|
|
||||||
XMEMCPY(exp + idx, keys->aead_enc_imp_IV, AEAD_MAX_IMP_SZ);
|
|
||||||
idx += AEAD_MAX_IMP_SZ;
|
|
||||||
XMEMCPY(exp + idx, keys->aead_dec_imp_IV, AEAD_MAX_IMP_SZ);
|
|
||||||
idx += AEAD_MAX_IMP_SZ;
|
|
||||||
|
|
||||||
c32toa(keys->peer_sequence_number, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(keys->peer_sequence_number, exp + idx); idx += OPAQUE32_LEN;
|
||||||
c32toa(keys->peer_sequence_number, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(keys->peer_sequence_number, exp + idx); idx += OPAQUE32_LEN;
|
||||||
@@ -594,8 +589,8 @@ static int ExportKeyState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
exp[idx++] = keys->decryptedCur;
|
exp[idx++] = keys->decryptedCur;
|
||||||
|
|
||||||
#ifdef WORD64_AVAILABLE
|
#ifdef WORD64_AVAILABLE
|
||||||
cw64toa(keys->dtls_state.window, exp + idx); idx += OPAQUE64_LEN;
|
c64toa(keys->dtls_state.window, exp + idx); idx += OPAQUE64_LEN;
|
||||||
cw64toa(keys->dtls_state.prevWindow, exp + idx); idx += OPAQUE64_LEN;
|
c64toa(keys->dtls_state.prevWindow, exp + idx); idx += OPAQUE64_LEN;
|
||||||
#else
|
#else
|
||||||
c32toa(keys->dtls_state.window, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(keys->dtls_state.window, exp + idx); idx += OPAQUE32_LEN;
|
||||||
c32toa(0, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(0, exp + idx); idx += OPAQUE32_LEN;
|
||||||
@@ -603,13 +598,42 @@ static int ExportKeyState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
c32toa(0, exp + idx); idx += OPAQUE32_LEN;
|
c32toa(0, exp + idx); idx += OPAQUE32_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (idx != DTLS_EXPORT_KEY_SZ) {
|
#ifdef HAVE_TRUNCATED_HMAC
|
||||||
|
sz = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ: ssl->specs.hash_size;
|
||||||
|
exp[idx++] = ssl->truncated_hmac;
|
||||||
|
#else
|
||||||
|
sz = ssl->specs.hash_size;
|
||||||
|
exp[idx++] = 0; /* no truncated hmac */
|
||||||
|
#endif
|
||||||
|
exp[idx++] = sz;
|
||||||
|
XMEMCPY(exp + idx, keys->client_write_MAC_secret, sz); idx += sz;
|
||||||
|
XMEMCPY(exp + idx, keys->server_write_MAC_secret, sz); idx += sz;
|
||||||
|
|
||||||
|
sz = ssl->specs.key_size;
|
||||||
|
exp[idx++] = sz;
|
||||||
|
XMEMCPY(exp + idx, keys->client_write_key, sz); idx += sz;
|
||||||
|
XMEMCPY(exp + idx, keys->server_write_key, sz); idx += sz;
|
||||||
|
|
||||||
|
sz = ssl->specs.iv_size;
|
||||||
|
exp[idx++] = sz;
|
||||||
|
XMEMCPY(exp + idx, keys->client_write_IV, sz); idx += sz;
|
||||||
|
XMEMCPY(exp + idx, keys->server_write_IV, sz); idx += sz;
|
||||||
|
XMEMCPY(exp + idx, keys->aead_exp_IV, AEAD_MAX_EXP_SZ);
|
||||||
|
idx += AEAD_MAX_EXP_SZ;
|
||||||
|
|
||||||
|
sz = AEAD_MAX_IMP_SZ;
|
||||||
|
exp[idx++] = sz;
|
||||||
|
XMEMCPY(exp + idx, keys->aead_enc_imp_IV, sz); idx += sz;
|
||||||
|
XMEMCPY(exp + idx, keys->aead_dec_imp_IV, sz); idx += sz;
|
||||||
|
|
||||||
|
if (idx > DTLS_EXPORT_KEY_SZ) {
|
||||||
WOLFSSL_MSG("DTLS_EXPORT_KEY_SZ needs updated and export version");
|
WOLFSSL_MSG("DTLS_EXPORT_KEY_SZ needs updated and export version");
|
||||||
return BUFFER_E;
|
return DTLS_EXPORT_VER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WOLFSSL_LEAVE("ExportKeyState", idx);
|
||||||
(void)ver;
|
(void)ver;
|
||||||
return 0;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ImportCipherSpecState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
static int ImportCipherSpecState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
||||||
@@ -617,6 +641,8 @@ static int ImportCipherSpecState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
CipherSpecs* specs;
|
CipherSpecs* specs;
|
||||||
|
|
||||||
|
WOLFSSL_ENTER("ImportCipherSpecState");
|
||||||
|
|
||||||
if (exp == NULL || ssl == NULL) {
|
if (exp == NULL || ssl == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
@@ -640,45 +666,30 @@ static int ImportCipherSpecState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
specs->pad_size = exp[idx++];
|
specs->pad_size = exp[idx++];
|
||||||
specs->static_ecdh = exp[idx++];
|
specs->static_ecdh = exp[idx++];
|
||||||
|
|
||||||
|
WOLFSSL_LEAVE("ImportCipherSpecState", idx);
|
||||||
(void)ver;
|
(void)ver;
|
||||||
return 0;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ImportKeyState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
static int ImportKeyState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
|
byte sz;
|
||||||
Keys* keys;
|
Keys* keys;
|
||||||
|
|
||||||
|
WOLFSSL_ENTER("ImportKeyState");
|
||||||
|
|
||||||
if (exp == NULL || ssl == NULL) {
|
if (exp == NULL || ssl == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
keys = &(ssl->keys);
|
keys = &(ssl->keys);
|
||||||
|
|
||||||
if (DTLS_EXPORT_KEY_SZ > len) {
|
/* check minimum length -- includes byte used for size indicators */
|
||||||
|
if (len < DTLS_EXPORT_MIN_KEY_SZ) {
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(keys->client_write_MAC_secret, exp + idx, MAX_DIGEST_SIZE);
|
|
||||||
idx += MAX_DIGEST_SIZE;
|
|
||||||
XMEMCPY(keys->server_write_MAC_secret, exp + idx, MAX_DIGEST_SIZE);
|
|
||||||
idx += MAX_DIGEST_SIZE;
|
|
||||||
XMEMCPY(keys->client_write_key, exp + idx, AES_256_KEY_SIZE);
|
|
||||||
idx += AES_256_KEY_SIZE;
|
|
||||||
XMEMCPY(keys->server_write_key, exp + idx, AES_256_KEY_SIZE);
|
|
||||||
idx += AES_256_KEY_SIZE;
|
|
||||||
XMEMCPY(keys->client_write_IV, exp + idx, MAX_WRITE_IV_SZ);
|
|
||||||
idx += MAX_WRITE_IV_SZ;
|
|
||||||
XMEMCPY(keys->server_write_IV, exp + idx, MAX_WRITE_IV_SZ);
|
|
||||||
idx += MAX_WRITE_IV_SZ;
|
|
||||||
XMEMCPY(keys->aead_exp_IV, exp + idx, AEAD_MAX_EXP_SZ);
|
|
||||||
idx += AEAD_MAX_EXP_SZ;
|
|
||||||
XMEMCPY(keys->aead_enc_imp_IV, exp + idx, AEAD_MAX_IMP_SZ);
|
|
||||||
idx += AEAD_MAX_IMP_SZ;
|
|
||||||
XMEMCPY(keys->aead_dec_imp_IV, exp + idx, AEAD_MAX_IMP_SZ);
|
|
||||||
idx += AEAD_MAX_IMP_SZ;
|
|
||||||
|
|
||||||
ato32(exp + idx, &keys->peer_sequence_number); idx += OPAQUE32_LEN;
|
ato32(exp + idx, &keys->peer_sequence_number); idx += OPAQUE32_LEN;
|
||||||
ato32(exp + idx, &keys->peer_sequence_number); idx += OPAQUE32_LEN;
|
ato32(exp + idx, &keys->peer_sequence_number); idx += OPAQUE32_LEN;
|
||||||
ato32(exp + idx, &keys->sequence_number); idx += OPAQUE32_LEN;
|
ato32(exp + idx, &keys->sequence_number); idx += OPAQUE32_LEN;
|
||||||
@@ -703,8 +714,8 @@ static int ImportKeyState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
keys->decryptedCur = exp[idx++];
|
keys->decryptedCur = exp[idx++];
|
||||||
|
|
||||||
#ifdef WORD64_AVAILABLE
|
#ifdef WORD64_AVAILABLE
|
||||||
atow64(exp + idx, &keys->dtls_state.window); idx += OPAQUE64_LEN;
|
ato64(exp + idx, &keys->dtls_state.window); idx += OPAQUE64_LEN;
|
||||||
atow64(exp + idx, &keys->dtls_state.prevWindow); idx += OPAQUE64_LEN;
|
ato64(exp + idx, &keys->dtls_state.prevWindow); idx += OPAQUE64_LEN;
|
||||||
#else
|
#else
|
||||||
ato32(exp + idx, &keys->dtls_state.window); idx += OPAQUE32_LEN;
|
ato32(exp + idx, &keys->dtls_state.window); idx += OPAQUE32_LEN;
|
||||||
ato32(exp + idx, 0); idx += OPAQUE32_LEN;
|
ato32(exp + idx, 0); idx += OPAQUE32_LEN;
|
||||||
@@ -712,8 +723,44 @@ static int ImportKeyState(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
ato32(exp + idx, 0); idx += OPAQUE32_LEN;
|
ato32(exp + idx, 0); idx += OPAQUE32_LEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_TRUNCATED_HMAC
|
||||||
|
ssl->truncated_hmac = exp[idx++];
|
||||||
|
#else
|
||||||
|
idx++; /* no truncated hmac */
|
||||||
|
#endif
|
||||||
|
sz = exp[idx++];
|
||||||
|
if (sz > MAX_DIGEST_SIZE || sz + idx > len) {
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
XMEMCPY(keys->client_write_MAC_secret, exp + idx, sz); idx += sz;
|
||||||
|
XMEMCPY(keys->server_write_MAC_secret, exp + idx, sz); idx += sz;
|
||||||
|
|
||||||
|
sz = exp[idx++];
|
||||||
|
if (sz > AES_256_KEY_SIZE || sz + idx > len) {
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
XMEMCPY(keys->client_write_key, exp + idx, sz); idx += sz;
|
||||||
|
XMEMCPY(keys->server_write_key, exp + idx, sz); idx += sz;
|
||||||
|
|
||||||
|
sz = exp[idx++];
|
||||||
|
if (sz > MAX_WRITE_IV_SZ || sz + idx > len) {
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
XMEMCPY(keys->client_write_IV, exp + idx, sz); idx += sz;
|
||||||
|
XMEMCPY(keys->server_write_IV, exp + idx, sz); idx += sz;
|
||||||
|
XMEMCPY(keys->aead_exp_IV, exp + idx, AEAD_MAX_EXP_SZ);
|
||||||
|
idx += AEAD_MAX_EXP_SZ;
|
||||||
|
|
||||||
|
sz = exp[idx++];
|
||||||
|
if (sz > AEAD_MAX_IMP_SZ || sz + idx > len) {
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
XMEMCPY(keys->aead_enc_imp_IV, exp + idx, sz); idx += sz;
|
||||||
|
XMEMCPY(keys->aead_dec_imp_IV, exp + idx, sz); idx += sz;
|
||||||
|
|
||||||
|
WOLFSSL_LEAVE("ImportKeyState", idx);
|
||||||
(void)ver;
|
(void)ver;
|
||||||
return 0;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -731,6 +778,8 @@ static int dtls_export_new(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMEMSET(exp, 0, DTLS_EXPORT_OPT_SZ);
|
||||||
|
|
||||||
/* these options are kept and sent to indicate verify status and strength
|
/* these options are kept and sent to indicate verify status and strength
|
||||||
* of handshake */
|
* of handshake */
|
||||||
exp[idx++] = options->sendVerify;
|
exp[idx++] = options->sendVerify;
|
||||||
@@ -817,7 +866,6 @@ static int dtls_export_new(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
exp[idx++] = options->acceptState;
|
exp[idx++] = options->acceptState;
|
||||||
exp[idx++] = options->keyShareState;
|
exp[idx++] = options->keyShareState;
|
||||||
|
|
||||||
|
|
||||||
/* version of connection */
|
/* version of connection */
|
||||||
exp[idx++] = ssl->version.major;
|
exp[idx++] = ssl->version.major;
|
||||||
exp[idx++] = ssl->version.minor;
|
exp[idx++] = ssl->version.minor;
|
||||||
@@ -828,12 +876,12 @@ static int dtls_export_new(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
/* check if changes were made and notify of need to update export version */
|
/* check if changes were made and notify of need to update export version */
|
||||||
if (idx != DTLS_EXPORT_OPT_SZ) {
|
if (idx != DTLS_EXPORT_OPT_SZ) {
|
||||||
WOLFSSL_MSG("Update DTLS_EXPORT_OPT_SZ and version of wolfSSL export");
|
WOLFSSL_MSG("Update DTLS_EXPORT_OPT_SZ and version of wolfSSL export");
|
||||||
return BUFFER_E;
|
return DTLS_EXPORT_VER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
WOLFSSL_LEAVE("dtls_export_new", 0);
|
WOLFSSL_LEAVE("dtls_export_new", idx);
|
||||||
|
|
||||||
return 0;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -945,7 +993,7 @@ static int dtls_export_load(byte* exp, word32 len, byte ver, WOLFSSL* ssl)
|
|||||||
return VERSION_ERROR;
|
return VERSION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -982,8 +1030,43 @@ int wolfSSL_dtls_export(byte* buf, word32 sz, WOLFSSL* ssl)
|
|||||||
buf[idx++] = ((byte)DTLS_EXPORT_PRO & 0xF0) |
|
buf[idx++] = ((byte)DTLS_EXPORT_PRO & 0xF0) |
|
||||||
((byte)DTLS_EXPORT_VERSION & 0X0F);
|
((byte)DTLS_EXPORT_VERSION & 0X0F);
|
||||||
|
|
||||||
c16toa((word16)(totalLen - DTLS_EXPORT_LEN), buf + idx);
|
idx += DTLS_EXPORT_LEN; /* leave spot for length */
|
||||||
|
|
||||||
|
c16toa((word16)DTLS_EXPORT_OPT_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
|
||||||
|
if ((ret = dtls_export_new(buf + idx, sz - idx, DTLS_EXPORT_VERSION,
|
||||||
|
ssl)) < 0) {
|
||||||
|
WOLFSSL_LEAVE("wolfSSL_dtls_export", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
idx += DTLS_EXPORT_OPT_SZ;
|
||||||
|
|
||||||
|
/* export keys struct and dtls state -- variable length stored in ret */
|
||||||
|
idx += DTLS_EXPORT_LEN; /* leave room for length */
|
||||||
|
if ((ret = ExportKeyState(buf + idx, sz - idx,
|
||||||
|
DTLS_EXPORT_VERSION, ssl)) < 0) {
|
||||||
|
WOLFSSL_LEAVE("wolfSSL_dtls_export", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
c16toa((word16)ret, buf + idx - DTLS_EXPORT_LEN); idx += ret;
|
||||||
|
|
||||||
|
/* export of cipher specs struct */
|
||||||
|
c16toa((word16)DTLS_EXPORT_SPC_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
|
||||||
|
if ((ret = ExportCipherSpecState(buf + idx, sz - idx,
|
||||||
|
DTLS_EXPORT_VERSION, ssl)) < 0) {
|
||||||
|
WOLFSSL_LEAVE("wolfSSL_dtls_export", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
idx += DTLS_EXPORT_SPC_SZ;
|
||||||
|
|
||||||
|
/* export of dtls peer information */
|
||||||
|
c16toa((word16)ssl->buffers.dtlsCtx.peer.sz, buf + idx);
|
||||||
idx += DTLS_EXPORT_LEN;
|
idx += DTLS_EXPORT_LEN;
|
||||||
|
XMEMCPY(buf + idx, ssl->buffers.dtlsCtx.peer.sa,
|
||||||
|
ssl->buffers.dtlsCtx.peer.sz);
|
||||||
|
idx += ssl->buffers.dtlsCtx.peer.sz;
|
||||||
|
|
||||||
|
/* place total length of exported buffer minus 2 bytes protocol/version */
|
||||||
|
c16toa((word16)(idx - DTLS_EXPORT_LEN), buf + DTLS_EXPORT_LEN);
|
||||||
|
|
||||||
/* if compiled with debug options then print the version, protocol, size */
|
/* if compiled with debug options then print the version, protocol, size */
|
||||||
#ifdef WOLFSSL_SESSION_EXPORT_DEBUG
|
#ifdef WOLFSSL_SESSION_EXPORT_DEBUG
|
||||||
@@ -991,42 +1074,11 @@ int wolfSSL_dtls_export(byte* buf, word32 sz, WOLFSSL* ssl)
|
|||||||
char debug[256];
|
char debug[256];
|
||||||
snprintf(debug, sizeof(debug), "Exporting DTLS session\n"
|
snprintf(debug, sizeof(debug), "Exporting DTLS session\n"
|
||||||
"\tVersion : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
|
"\tVersion : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
|
||||||
, (int)DTLS_EXPORT_VERSION, buf[0], (buf[1] >> 4), totalLen - 2);
|
, (int)DTLS_EXPORT_VERSION, buf[0], (buf[1] >> 4), idx - 2);
|
||||||
WOLFSSL_MSG(debug);
|
WOLFSSL_MSG(debug);
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
|
#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
|
||||||
|
|
||||||
c16toa((word16)DTLS_EXPORT_OPT_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
|
|
||||||
if ((ret = dtls_export_new(buf + idx, sz - idx, DTLS_EXPORT_VERSION,
|
|
||||||
ssl)) != 0) {
|
|
||||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
idx += DTLS_EXPORT_OPT_SZ;
|
|
||||||
|
|
||||||
/* export keys struct and dtls state */
|
|
||||||
c16toa((word16)DTLS_EXPORT_KEY_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
|
|
||||||
if ((ret = ExportKeyState(buf + idx, sz - idx,
|
|
||||||
DTLS_EXPORT_VERSION, ssl)) != 0) {
|
|
||||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
idx += DTLS_EXPORT_KEY_SZ;
|
|
||||||
|
|
||||||
c16toa((word16)DTLS_EXPORT_SPC_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
|
|
||||||
if ((ret = ExportCipherSpecState(buf + idx, sz - idx,
|
|
||||||
DTLS_EXPORT_VERSION, ssl)) != 0) {
|
|
||||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
idx += DTLS_EXPORT_SPC_SZ;
|
|
||||||
|
|
||||||
c16toa((word16)ssl->buffers.dtlsCtx.peer.sz, buf + idx);
|
|
||||||
idx += DTLS_EXPORT_LEN;
|
|
||||||
XMEMCPY(buf + idx, ssl->buffers.dtlsCtx.peer.sa,
|
|
||||||
ssl->buffers.dtlsCtx.peer.sz);
|
|
||||||
idx += ssl->buffers.dtlsCtx.peer.sz;
|
|
||||||
|
|
||||||
WOLFSSL_LEAVE("wolfSSL_dtls_export", idx);
|
WOLFSSL_LEAVE("wolfSSL_dtls_export", idx);
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
@@ -1073,51 +1125,62 @@ int wolfSSL_dtls_import_internal(byte* buf, word32 sz, WOLFSSL* ssl)
|
|||||||
|
|
||||||
/* perform sanity checks and extract Options information used */
|
/* perform sanity checks and extract Options information used */
|
||||||
if (DTLS_EXPORT_LEN + DTLS_EXPORT_OPT_SZ + idx > sz) {
|
if (DTLS_EXPORT_LEN + DTLS_EXPORT_OPT_SZ + idx > sz) {
|
||||||
|
WOLFSSL_MSG("Import Options struct error");
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
||||||
if (length != DTLS_EXPORT_OPT_SZ) {
|
if (length != DTLS_EXPORT_OPT_SZ) {
|
||||||
|
WOLFSSL_MSG("Import Options struct error");
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
if ((ret = dtls_export_load(buf + idx, length, version, ssl)) != 0) {
|
if ((ret = dtls_export_load(buf + idx, length, version, ssl)) < 0) {
|
||||||
return ret;
|
WOLFSSL_MSG("Import Options struct error");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
idx += length;
|
idx += length;
|
||||||
|
|
||||||
/* perform sanity checks and extract Keys struct */
|
/* perform sanity checks and extract Keys struct */
|
||||||
if (DTLS_EXPORT_LEN + DTLS_EXPORT_KEY_SZ + idx > sz) {
|
if (DTLS_EXPORT_LEN + idx > sz) {
|
||||||
|
WOLFSSL_MSG("Import Key struct error");
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
||||||
if (length != DTLS_EXPORT_KEY_SZ || length + idx > sz) {
|
if (length > DTLS_EXPORT_KEY_SZ || length + idx > sz) {
|
||||||
|
WOLFSSL_MSG("Import Key struct error");
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
if ((ret = ImportKeyState(buf + idx, length, version, ssl)) != 0) {
|
if ((ret = ImportKeyState(buf + idx, length, version, ssl)) < 0) {
|
||||||
|
WOLFSSL_MSG("Import Key struct error");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
idx += DTLS_EXPORT_KEY_SZ;
|
idx += ret;
|
||||||
|
|
||||||
/* perform sanity checks and extract CipherSpecs struct */
|
/* perform sanity checks and extract CipherSpecs struct */
|
||||||
if (DTLS_EXPORT_LEN + DTLS_EXPORT_SPC_SZ + idx > sz) {
|
if (DTLS_EXPORT_LEN + DTLS_EXPORT_SPC_SZ + idx > sz) {
|
||||||
|
WOLFSSL_MSG("Import CipherSpecs struct error");
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
||||||
if ( length != DTLS_EXPORT_SPC_SZ) {
|
if ( length != DTLS_EXPORT_SPC_SZ) {
|
||||||
|
WOLFSSL_MSG("Import CipherSpecs struct error");
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
if ((ret = ImportCipherSpecState(buf + idx, length, version, ssl)) != 0) {
|
if ((ret = ImportCipherSpecState(buf + idx, length, version, ssl)) < 0) {
|
||||||
|
WOLFSSL_MSG("Import CipherSpecs struct error");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
idx += length;
|
idx += length;
|
||||||
|
|
||||||
/* perform sanity checks and extract DTLS peer info */
|
/* perform sanity checks and extract DTLS peer info */
|
||||||
if (DTLS_EXPORT_LEN + idx > sz) {
|
if (DTLS_EXPORT_LEN + idx > sz) {
|
||||||
|
WOLFSSL_MSG("Import DTLS peer info error");
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
|
||||||
ssl->buffers.dtlsCtx.peer.sz = length;
|
ssl->buffers.dtlsCtx.peer.sz = length;
|
||||||
|
|
||||||
if (idx + ssl->buffers.dtlsCtx.peer.sz > sz) {
|
if (idx + ssl->buffers.dtlsCtx.peer.sz > sz) {
|
||||||
|
WOLFSSL_MSG("Import DTLS peer info error");
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1125,6 +1188,7 @@ int wolfSSL_dtls_import_internal(byte* buf, word32 sz, WOLFSSL* ssl)
|
|||||||
ssl->buffers.dtlsCtx.peer.sa = XMALLOC(ssl->buffers.dtlsCtx.peer.sz,
|
ssl->buffers.dtlsCtx.peer.sa = XMALLOC(ssl->buffers.dtlsCtx.peer.sz,
|
||||||
ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (ssl->buffers.dtlsCtx.peer.sa == NULL) {
|
if (ssl->buffers.dtlsCtx.peer.sa == NULL) {
|
||||||
|
WOLFSSL_MSG("Import DTLS peer info error");
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1141,7 +1205,7 @@ int wolfSSL_dtls_import_internal(byte* buf, word32 sz, WOLFSSL* ssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* make sure is a valid suite used */
|
/* make sure is a valid suite used */
|
||||||
ret = SUITES_ERROR;
|
ret = MATCH_SUITE_ERROR;
|
||||||
for (i = 0; i < ssl->suites->suiteSz; i += 2) {
|
for (i = 0; i < ssl->suites->suiteSz; i += 2) {
|
||||||
if (ssl->suites->suites[i] == ssl->options.cipherSuite0 &&
|
if (ssl->suites->suites[i] == ssl->options.cipherSuite0 &&
|
||||||
ssl->suites->suites[i+1] == ssl->options.cipherSuite) {
|
ssl->suites->suites[i+1] == ssl->options.cipherSuite) {
|
||||||
@@ -1150,9 +1214,16 @@ int wolfSSL_dtls_import_internal(byte* buf, word32 sz, WOLFSSL* ssl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
WOLFSSL_MSG("Can not match cipher suite imported");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* do not allow stream ciphers with DTLS */
|
||||||
|
if (ssl->specs.cipher_type == stream) {
|
||||||
|
WOLFSSL_MSG("Can not import stream ciphers for DTLS");
|
||||||
|
return SANITY_CIPHER_E;
|
||||||
|
}
|
||||||
|
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_DTLS */
|
#endif /* WOLFSSL_DTLS */
|
||||||
@@ -10935,6 +11006,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
|
|||||||
case ECC_KEY_SIZE_E:
|
case ECC_KEY_SIZE_E:
|
||||||
return "ECC key too small";
|
return "ECC key too small";
|
||||||
|
|
||||||
|
case DTLS_EXPORT_VER_E:
|
||||||
|
return "Version needs updated after code change or version mismatch";
|
||||||
|
|
||||||
default :
|
default :
|
||||||
return "unknown error number";
|
return "unknown error number";
|
||||||
}
|
}
|
||||||
|
@@ -146,6 +146,8 @@ enum wolfSSL_ErrorCodes {
|
|||||||
|
|
||||||
RSA_KEY_SIZE_E = -409, /* RSA key too small */
|
RSA_KEY_SIZE_E = -409, /* RSA key too small */
|
||||||
ECC_KEY_SIZE_E = -410, /* ECC key too small */
|
ECC_KEY_SIZE_E = -410, /* ECC key too small */
|
||||||
|
|
||||||
|
DTLS_EXPORT_VER_E = -411, /* export version error */
|
||||||
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
|
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
|
||||||
|
|
||||||
/* begin negotiation parameter errors */
|
/* begin negotiation parameter errors */
|
||||||
|
@@ -952,8 +952,9 @@ enum Misc {
|
|||||||
DTLS_POOL_SZ = 5, /* buffers to hold in the retry pool */
|
DTLS_POOL_SZ = 5, /* buffers to hold in the retry pool */
|
||||||
DTLS_EXPORT_PRO = 165,/* wolfSSL protocol for serialized session */
|
DTLS_EXPORT_PRO = 165,/* wolfSSL protocol for serialized session */
|
||||||
DTLS_EXPORT_VERSION = 1, /* wolfSSL version for serialized session */
|
DTLS_EXPORT_VERSION = 1, /* wolfSSL version for serialized session */
|
||||||
DTLS_EXPORT_OPT_SZ = 57, /* amount of bytes used from Options */
|
DTLS_EXPORT_OPT_SZ = 57, /* amount of bytes used from Options */
|
||||||
DTLS_EXPORT_KEY_SZ = 326, /* amount of bytes used from Keys */
|
DTLS_EXPORT_KEY_SZ = 331,/* max amount of bytes used from Keys */
|
||||||
|
DTLS_EXPORT_MIN_KEY_SZ = 75, /* min amount of bytes used from Keys */
|
||||||
DTLS_EXPORT_SPC_SZ = 16, /* amount of bytes used from CipherSpecs */
|
DTLS_EXPORT_SPC_SZ = 16, /* amount of bytes used from CipherSpecs */
|
||||||
DTLS_EXPORT_LEN = 2, /* 2 bytes for length and protocol */
|
DTLS_EXPORT_LEN = 2, /* 2 bytes for length and protocol */
|
||||||
MAX_EXPORT_BUFFER = 500, /* max size of buffer for exporting */
|
MAX_EXPORT_BUFFER = 500, /* max size of buffer for exporting */
|
||||||
|
Reference in New Issue
Block a user