DTLS Multicast

1. Temporary change to io.c to recieve datagrams from any peer.
2. Uses an array of Peer Sequence structures to track the current
   sequence number of all the peers.
This commit is contained in:
John Safranek
2017-01-05 08:36:09 -08:00
parent 0457df83d4
commit fa4a8fee8c
4 changed files with 89 additions and 48 deletions

View File

@@ -9609,16 +9609,22 @@ static INLINE int DtlsCheckWindow(WOLFSSL* ssl)
word16 cur_hi, next_hi;
word32 cur_lo, next_lo, diff;
int curLT;
WOLFSSL_DTLS_PEERSEQ* peerSeq = ssl->keys.peerSeq;
if (ssl->keys.curEpoch == ssl->keys.nextEpoch) {
next_hi = ssl->keys.nextSeq_hi;
next_lo = ssl->keys.nextSeq_lo;
window = ssl->keys.window;
#ifdef WOLFSSL_MULTICAST
if (ssl->options.haveMcast)
peerSeq += ssl->keys.curPeerId;
#endif
if (ssl->keys.curEpoch == peerSeq->nextEpoch) {
next_hi = peerSeq->nextSeq_hi;
next_lo = peerSeq->nextSeq_lo;
window = peerSeq->window;
}
else if (ssl->keys.curEpoch == ssl->keys.nextEpoch - 1) {
next_hi = ssl->keys.prevSeq_hi;
next_lo = ssl->keys.prevSeq_lo;
window = ssl->keys.prevWindow;
else if (ssl->keys.curEpoch == peerSeq->nextEpoch - 1) {
next_hi = peerSeq->prevSeq_hi;
next_lo = peerSeq->prevSeq_lo;
window = peerSeq->prevWindow;
}
else {
return 0;
@@ -9684,16 +9690,22 @@ static INLINE int DtlsUpdateWindow(WOLFSSL* ssl)
int curLT;
word32 cur_lo, diff;
word16 cur_hi;
WOLFSSL_DTLS_PEERSEQ* peerSeq = ssl->keys.peerSeq;
if (ssl->keys.curEpoch == ssl->keys.nextEpoch) {
next_hi = &ssl->keys.nextSeq_hi;
next_lo = &ssl->keys.nextSeq_lo;
window = ssl->keys.window;
#ifdef WOLFSSL_MULTICAST
if (ssl->options.haveMcast)
peerSeq += ssl->keys.curPeerId;
#endif
if (ssl->keys.curEpoch == peerSeq->nextEpoch) {
next_hi = &peerSeq->nextSeq_hi;
next_lo = &peerSeq->nextSeq_lo;
window = peerSeq->window;
}
else {
next_hi = &ssl->keys.prevSeq_hi;
next_lo = &ssl->keys.prevSeq_lo;
window = ssl->keys.prevWindow;
next_hi = &peerSeq->prevSeq_hi;
next_lo = &peerSeq->prevSeq_lo;
window = peerSeq->prevWindow;
}
cur_hi = ssl->keys.curSeq_hi;
@@ -11727,20 +11739,28 @@ int ProcessReply(WOLFSSL* ssl)
ssl->keys.encryptionOn = 1;
/* setup decrypt keys for following messages */
/* XXX This might not be what we want to do when
* receiving a CCS with multicast. We update the
* key when the application updates them. */
if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
return ret;
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
WOLFSSL_DTLS_PEERSEQ* peerSeq = ssl->keys.peerSeq;
#ifdef WOLFSSL_MULTICAST
if (ssl->options.haveMcast)
peerSeq += ssl->keys.curPeerId;
#endif
DtlsMsgPoolReset(ssl);
ssl->keys.prevSeq_lo = ssl->keys.nextSeq_lo;
ssl->keys.prevSeq_hi = ssl->keys.nextSeq_hi;
XMEMCPY(ssl->keys.prevWindow, ssl->keys.window,
peerSeq->nextEpoch++;
peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
peerSeq->nextSeq_lo = 0;
peerSeq->nextSeq_hi = 0;
XMEMCPY(peerSeq->prevWindow, peerSeq->window,
DTLS_SEQ_SZ);
ssl->keys.nextEpoch++;
ssl->keys.nextSeq_lo = 0;
ssl->keys.nextSeq_hi = 0;
XMEMSET(ssl->keys.window, 0, DTLS_SEQ_SZ);
XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
}
#endif

View File

@@ -293,12 +293,12 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
}
}
else {
if (dtlsCtx->peer.sz > 0
&& peerSz != (XSOCKLENT)dtlsCtx->peer.sz
&& XMEMCMP(&peer, dtlsCtx->peer.sa, peerSz) != 0) {
WOLFSSL_MSG("\tIgnored packet from invalid peer");
return WOLFSSL_CBIO_ERR_WANT_READ;
}
// if (dtlsCtx->peer.sz > 0
// && peerSz != (XSOCKLENT)dtlsCtx->peer.sz
// && XMEMCMP(&peer, dtlsCtx->peer.sa, peerSz) != 0) {
// WOLFSSL_MSG(" Ignored packet from invalid peer");
// return WOLFSSL_CBIO_ERR_WANT_READ;
// }
}
return recvd;

View File

@@ -852,7 +852,7 @@ int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, byte id)
WOLFSSL_ENTER("wolfSSL_CTX_mcast_set_member_id()");
if (ctx == NULL)
if (ctx == NULL || id >= MULTICAST_SZ)
ret = BAD_FUNC_ARG;
if (ret == 0) {
@@ -906,14 +906,22 @@ int wolfSSL_set_secret(WOLFSSL* ssl, unsigned short epoch,
if (ret == 0) {
if (ssl->options.dtls) {
#ifdef WOLFSSL_DTLS
WOLFSSL_DTLS_PEERSEQ* peerSeq;
int i;
ssl->keys.dtls_epoch = epoch;
ssl->keys.nextEpoch = epoch;
ssl->keys.prevSeq_lo = ssl->keys.nextSeq_lo;
ssl->keys.prevSeq_hi = ssl->keys.nextSeq_hi;
ssl->keys.nextSeq_lo = 0;
ssl->keys.nextSeq_hi = 0;
XMEMCPY(ssl->keys.prevWindow, ssl->keys.window, DTLS_SEQ_SZ);
XMEMSET(ssl->keys.window, 0, DTLS_SEQ_SZ);
for (i = 0, peerSeq = ssl->keys.peerSeq;
i < WOLFSSL_MULTICAST_PEERS;
i++, peerSeq++) {
peerSeq->nextEpoch = epoch;
peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
peerSeq->nextSeq_lo = 0;
peerSeq->nextSeq_hi = 0;
XMEMCPY(peerSeq->prevWindow, peerSeq->window, DTLS_SEQ_SZ);
XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
}
#endif
}
ret = SSL_SUCCESS;

View File

@@ -914,6 +914,15 @@ enum {
#define DTLS_SEQ_BITS (WOLFSSL_DTLS_WINDOW_WORDS * DTLS_WORD_BITS)
#define DTLS_SEQ_SZ (sizeof(word32) * WOLFSSL_DTLS_WINDOW_WORDS)
#ifndef WOLFSSL_MULTICAST_PEERS
/* max allowed multicast group peers */
#ifdef WOLFSSL_MULTICAST
#define WOLFSSL_MULTICAST_PEERS 100
#else
#define WOLFSSL_MULTICAST_PEERS 1
#endif
#endif /* WOLFSSL_MULTICAST_PEERS */
enum Misc {
ECC_BYTE = 0xC0, /* ECC first cipher suite byte */
@@ -1035,7 +1044,7 @@ enum Misc {
DTLS_EXPORT_LEN = 2, /* 2 bytes for length and protocol */
DTLS_EXPORT_IP = 46, /* max ip size IPv4 mapped IPv6 */
MAX_EXPORT_BUFFER = 514, /* max size of buffer for exporting */
MULTICAST_SZ = 100, /* max allowed multicast group peers */
MULTICAST_SZ = WOLFSSL_MULTICAST_PEERS,
FINISHED_LABEL_SZ = 15, /* TLS finished label size */
TLS_FINISHED_SZ = 12, /* TLS has a shorter size */
EXT_MASTER_LABEL_SZ = 22, /* TLS extended master secret label sz */
@@ -1724,6 +1733,20 @@ typedef struct WOLFSSL_DTLS_CTX {
} WOLFSSL_DTLS_CTX;
typedef struct WOLFSSL_DTLS_PEERSEQ {
word32 window[WOLFSSL_DTLS_WINDOW_WORDS];
/* Sliding window for current epoch */
word16 nextEpoch; /* Expected epoch in next record */
word16 nextSeq_hi; /* Expected sequence in next record */
word32 nextSeq_lo;
word32 prevWindow[WOLFSSL_DTLS_WINDOW_WORDS];
/* Sliding window for old epoch */
word16 prevSeq_hi; /* Next sequence in allowed old epoch */
word32 prevSeq_lo;
} WOLFSSL_DTLS_PEERSEQ;
#define MAX_WRITE_IV_SZ 16 /* max size of client/server write_IV */
/* keys and secrets
@@ -1747,23 +1770,13 @@ typedef struct Keys {
word32 sequence_number_lo;
#ifdef WOLFSSL_DTLS
word32 window[WOLFSSL_DTLS_WINDOW_WORDS];
/* Sliding window for current epoch */
word16 nextEpoch; /* Expected epoch in next record */
word16 nextSeq_hi; /* Expected sequence in next record */
word32 nextSeq_lo;
word16 curEpoch; /* Received epoch in current record */
word16 curSeq_hi; /* Received sequence in current record */
word32 curSeq_lo;
#ifdef WOLFSSL_MULTICAST
byte curPeerId; /* Received peer group ID in current record */
#endif
word32 prevWindow[WOLFSSL_DTLS_WINDOW_WORDS];
/* Sliding window for old epoch */
word16 prevSeq_hi; /* Next sequence in allowed old epoch */
word32 prevSeq_lo;
WOLFSSL_DTLS_PEERSEQ peerSeq[WOLFSSL_MULTICAST_PEERS];
word16 dtls_peer_handshake_number;
word16 dtls_expected_peer_handshake_number;