diff --git a/configure.ac b/configure.ac index 2881d80f0..6cc2e2e10 100644 --- a/configure.ac +++ b/configure.ac @@ -3564,6 +3564,12 @@ AS_IF([(test "x$ENABLED_DTLS" = "xno") && \ [AM_CFLAGS="-DWOLFSSL_DTLS $AM_CFLAGS" ENABLED_DTLS=yes]) +# Multicast requires the null cipher +AS_IF([test "x$ENABLED_NULL_CIPHER" = "xno" && \ + test "x$ENABLED_MCAST" = "xyes"], + [AM_CFLAGS="-DHAVE_NULL_CIPHER $AM_CFLAGS" + ENABLED_NULL_CIPHER=yes]) + ################################################################################ # OPTIMIZE FLAGS diff --git a/examples/client/client.c b/examples/client/client.c index 52f1ab828..42816bdbe 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -752,8 +752,12 @@ static void Usage(void) #ifdef WOLFSSL_EARLY_DATA printf("-0 Early data sent to server (0-RTT handshake)\n"); #endif +#ifdef WOLFSSL_MULTICAST + printf("-3 Multicast, grpid < 256\n"); +#endif } + THREAD_RETURN WOLFSSL_THREAD client_test(void* args) { SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID; @@ -793,6 +797,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int doDTLS = 0; int dtlsUDP = 0; int dtlsSCTP = 0; + int doMcast = 0; int matchName = 0; int doPeerCheck = 1; int nonBlocking = 0; @@ -856,6 +861,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef WOLFSSL_EARLY_DATA int earlyData = 0; #endif + byte mcastID = 0; #ifdef HAVE_OCSP int useOcsp = 0; @@ -897,6 +903,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)updateKeysIVs; (void)useX25519; (void)helloRetry; + (void)mcastID; StackTrap(); @@ -905,7 +912,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) while ((ch = mygetopt(argc, argv, "?" "ab:c:defgh:ijk:l:mnop:q:rstuv:wxyz" "A:B:CDE:F:GHIJKL:M:NO:PQRS:TUVW:XYZ:" - "0")) != -1) { + "03:")) != -1) { switch (ch) { case '?' : Usage(); @@ -1175,6 +1182,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif break; +<<<<<<< HEAD case 'J' : #ifdef WOLFSSL_TLS13 helloRetry = 1; @@ -1231,6 +1239,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif break; + case '3' : + #ifdef WOLFSSL_MULTICAST + doMcast = 1; + mcastID = (byte)(atoi(myoptarg) & 0xFF); + #endif + break; + default: Usage(); exit(MY_EX_USAGE); @@ -1660,6 +1675,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_CTX_allow_post_handshake_auth(ctx); #endif + if (doMcast) { +#ifdef WOLFSSL_MULTICAST + wolfSSL_CTX_mcast_set_member_id(ctx, mcastID); + if (wolfSSL_CTX_set_cipher_list(ctx, "WDM-NULL-SHA256") != SSL_SUCCESS) + err_sys("Couldn't set multicast cipher list."); +#endif + } + ssl = wolfSSL_new(ctx); if (ssl == NULL) { wolfSSL_CTX_free(ctx); @@ -1705,6 +1728,23 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif + if (doMcast) { +#ifdef WOLFSSL_MULTICAST + byte pms[512]; + byte cr[32]; + byte sr[32]; + const byte suite[2] = {0, 0xfe}; /* WDM_WITH_NULL_SHA256 */ + + XMEMSET(pms, 0x23, sizeof(pms)); + XMEMSET(cr, 0xA5, sizeof(cr)); + XMEMSET(sr, 0x5A, sizeof(sr)); + + if (wolfSSL_set_secret(ssl, 1, pms, sizeof(pms), cr, sr, suite) + != SSL_SUCCESS) + err_sys("unable to set mcast secret"); +#endif + } + #ifdef HAVE_SESSION_TICKET wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session"); #endif diff --git a/examples/server/server.c b/examples/server/server.c index 2c85e4c4c..60ee22007 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -416,6 +416,9 @@ static void Usage(void) #ifdef WOLFSSL_EARLY_DATA printf("-0 Early data read from client (0-RTT handshake)\n"); #endif +#ifdef WOLFSSL_MULTICAST + printf("-3 Multicast, grpid < 256\n"); +#endif } THREAD_RETURN CYASSL_THREAD server_test(void* args) @@ -445,6 +448,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) int doDTLS = 0; int dtlsUDP = 0; int dtlsSCTP = 0; + int doMcast = 0; int needDH = 0; int useNtruKey = 0; int nonBlocking = 0; @@ -510,6 +514,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #ifdef WOLFSSL_SEND_HRR_COOKIE int hrrCookie = 0; #endif + byte mcastID = 0; #ifdef WOLFSSL_STATIC_MEMORY #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \ @@ -546,6 +551,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) (void)crlFlags; (void)readySignal; (void)updateKeysIVs; + (void)mcastID; #ifdef CYASSL_TIRTOS fdOpenSession(Task_self()); @@ -558,7 +564,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) while ((ch = mygetopt(argc, argv, "?" "abc:defgijk:l:nop:q:rsuv:wx" "A:B:C:D:E:GHIJKL:NO:PQR:S:UYZ:" - "0")) != -1) { + "03:")) != -1) { switch (ch) { case '?' : Usage(); @@ -795,6 +801,13 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif break; + case '3' : + #ifdef WOLFSSL_MULTICAST + doMcast = 1; + mcastID = (byte)(atoi(myoptarg) & 0xFF); + #endif + break; + default: Usage(); exit(MY_EX_USAGE); @@ -1119,6 +1132,14 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } #endif + if (doMcast) { +#ifdef WOLFSSL_MULTICAST + wolfSSL_CTX_mcast_set_member_id(ctx, mcastID); + if (wolfSSL_CTX_set_cipher_list(ctx, "WDM-NULL-SHA256") != SSL_SUCCESS) + err_sys("Couldn't set multicast cipher list."); +#endif + } + ssl = SSL_new(ctx); if (ssl == NULL) err_sys_ex(runWithErrors, "unable to get SSL"); @@ -1143,6 +1164,23 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } #endif + if (doMcast) { +#ifdef WOLFSSL_MULTICAST + byte pms[512]; + byte cr[32]; + byte sr[32]; + const byte suite[2] = {0, 0xfe}; /* WDM_WITH_NULL_SHA256 */ + + XMEMSET(pms, 0x23, sizeof(pms)); + XMEMSET(cr, 0xA5, sizeof(cr)); + XMEMSET(sr, 0x5A, sizeof(sr)); + + if (wolfSSL_set_secret(ssl, 1, pms, sizeof(pms), cr, sr, suite) + != SSL_SUCCESS) + err_sys("unable to set mcast secret"); +#endif + } + #ifndef NO_HANDSHAKE_DONE_CB wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL); #endif diff --git a/src/internal.c b/src/internal.c index 161243dbc..3608df49c 100755 --- a/src/internal.c +++ b/src/internal.c @@ -4281,6 +4281,23 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #ifdef HAVE_SESSION_TICKET ssl->session.ticket = ssl->session.staticTicket; #endif + +#ifdef WOLFSSL_MULTICAST + if (ctx->haveMcast) { + ssl->options.haveMcast = 1; + ssl->options.mcastID = ctx->mcastID; + + /* Force the state to look like handshake has completed. */ + /* Keying material is supplied externally. */ + ssl->options.serverState = SERVER_FINISHED_COMPLETE; + ssl->options.clientState = CLIENT_FINISHED_COMPLETE; + ssl->options.connectState = SECOND_REPLY_DONE; + ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE; + ssl->options.handShakeState = HANDSHAKE_DONE; + ssl->options.handShakeDone = 1; + } +#endif + return 0; } @@ -7060,6 +7077,10 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) return 1; break; #endif +#ifdef WOLFSSL_MULTICAST + case WDM_WITH_NULL_SHA256 : + break; +#endif default: WOLFSSL_MSG("Unsupported cipher suite, CipherRequires"); diff --git a/src/ssl.c b/src/ssl.c index 69f23104d..402d3ce72 100755 --- a/src/ssl.c +++ b/src/ssl.c @@ -856,8 +856,8 @@ int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, byte id) ret = BAD_FUNC_ARG; if (ret == 0) { - /* check if side == MASTER. only work for client */ ctx->haveEMS = 0; + ctx->haveMcast = 1; ctx->mcastID = id; } @@ -900,6 +900,11 @@ int wolfSSL_set_secret(WOLFSSL* ssl, unsigned short epoch, if (ret == 0) ret = MakeTlsMasterSecret(ssl); + if (ret == 0) { + ssl->keys.encryptionOn = 1; + ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE); + } + if (ret == 0) ret = SSL_SUCCESS; else { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 554551e80..5482ad724 100755 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2241,6 +2241,7 @@ struct WOLFSSL_CTX { byte postHandshakeAuth:1; /* Post-handshake auth supported. */ #endif #ifdef WOLFSSL_MULTICAST + byte haveMcast; /* multicast requested */ byte mcastID; /* multicast group ID */ #endif #if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) @@ -2824,6 +2825,7 @@ typedef struct Options { word16 saveArrays:1; /* save array Memory for user get keys or psk */ word16 weOwnRng:1; /* will be true unless CTX owns */ + word16 haveEMS:1; /* using extended master secret */ #ifdef HAVE_POLY1305 word16 oldPoly:1; /* set when to use old rfc way of poly*/ #endif @@ -2843,9 +2845,9 @@ typedef struct Options { #ifdef WOLFSSL_SCTP word16 dtlsSctp:1; /* DTLS-over-SCTP mode */ #endif -#ifdef WOLFSSL_MULTICAST - word16 dtlsMcast:1; /* using multicast ? */ #endif +#ifdef WOLFSSL_MULTICAST + word16 haveMcast:1; /* using multicast ? */ #endif word16 haveEMS:1; /* using extended master secret */ #if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_SUPPORTED_CURVES) @@ -2874,6 +2876,9 @@ typedef struct Options { byte acceptState; /* nonblocking resume */ byte asyncState; /* sub-state for enum asyncState */ byte buildMsgState; /* sub-state for enum buildMsgState */ +#ifdef WOLFSSL_MULTICAST + byte mcastID; /* Multicast group ID */ +#endif #ifndef NO_DH word16 minDhKeySz; /* minimum DH key size */ word16 dhKeySz; /* actual DH key size */