diff --git a/examples/client/client.c b/examples/client/client.c index 2f8d363ae..793dd6521 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1313,7 +1313,7 @@ static const char* client_usage_msg[][70] = { " P384_KYBER_LEVEL3, P521_KYBER_LEVEL5, P256_KYBER_90S_LEVEL1, P384_KYBER_90S_LEVEL3,\n" " P521_KYBER_90S_LEVEL5]\n", /* 70 */ #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP "--srtp (default is SRTP_AES128_CM_SHA1_80)\n", /* 71 */ #endif "\n" @@ -1527,7 +1527,7 @@ static const char* client_usage_msg[][70] = { " P384_KYBER_LEVEL3, P521_KYBER_LEVEL5, P256_KYBER_90S_LEVEL1, P384_KYBER_90S_LEVEL3,\n" " P521_KYBER_90S_LEVEL5]\n", /* 70 */ #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP "--srtp (default is SRTP_AES128_CM_SHA1_80)\n", /* 71 */ #endif "\n" @@ -1754,7 +1754,7 @@ static void Usage(void) printf("%s", msg[++msgid]); /* more --pqc options */ printf("%s", msg[++msgid]); /* more --pqc options */ #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP printf("%s", msg[++msgid]); /* dtls-srtp */ #endif } @@ -1801,7 +1801,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #if defined(HAVE_PQC) { "pqc", 1, 259 }, #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP { "srtp", 2, 260 }, /* optional argument */ #endif { 0, 0, 0 } @@ -1925,8 +1925,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) int useCertFolder = 0; #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) - const char* dtlsSrtpProfile = NULL; +#ifdef WOLFSSL_SRTP + const char* dtlsSrtpProfiles = NULL; #endif char buffer[WOLFSSL_MAX_ERROR_SZ]; @@ -2066,12 +2066,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif break; - #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) + #ifdef WOLFSSL_SRTP case 260: doDTLS = 1; dtlsUDP = 1; - dtlsSrtpProfile = myoptarg != NULL ? myoptarg : + dtlsSrtpProfiles = myoptarg != NULL ? myoptarg : "SRTP_AES128_CM_SHA1_80"; + printf("Using SRTP Profile(s): %s\n", dtlsSrtpProfiles); break; #endif @@ -2831,9 +2832,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) - if (dtlsSrtpProfile != NULL) { - if (wolfSSL_CTX_set_tlsext_use_srtp(ctx, dtlsSrtpProfile) +#ifdef WOLFSSL_SRTP + if (dtlsSrtpProfiles != NULL) { + if (wolfSSL_CTX_set_tlsext_use_srtp(ctx, dtlsSrtpProfiles) != WOLFSSL_SUCCESS) { err_sys("unable to set DTLS SRTP profile"); } diff --git a/examples/server/server.c b/examples/server/server.c index a1356c3f0..7bc3082e2 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -955,7 +955,7 @@ static const char* server_usage_msg[][60] = { " P384_KYBER_LEVEL3, P521_KYBER_LEVEL5, P256_KYBER_90S_LEVEL1, P384_KYBER_90S_LEVEL3,\n" " P521_KYBER_90S_LEVEL5]\n", /* 60 */ #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP "--srtp (default is SRTP_AES128_CM_SHA1_80)\n", /* 61 */ #endif "\n" @@ -1123,7 +1123,7 @@ static const char* server_usage_msg[][60] = { " P384_KYBER_LEVEL3, P521_KYBER_LEVEL5, P256_KYBER_90S_LEVEL1, P384_KYBER_90S_LEVEL3,\n" " P521_KYBER_90S_LEVEL5]\n", /* 60 */ #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP "--srtp (default is SRTP_AES128_CM_SHA1_80)\n", /* 61 */ #endif "\n" @@ -1274,7 +1274,7 @@ static void Usage(void) printf("%s", msg[++msgId]); /* more --pqc options */ printf("%s", msg[++msgId]); /* more --pqc options */ #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP printf("%s", msg[++msgId]); /* dtls-srtp */ #endif } @@ -1307,7 +1307,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #if defined(HAVE_PQC) { "pqc", 1, 259 }, #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP { "srtp", 2, 260 }, /* optional argument */ #endif { 0, 0, 0 } @@ -1475,8 +1475,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) int useCertFolder = 0; #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) - const char* dtlsSrtpProfile = NULL; +#ifdef WOLFSSL_SRTP + const char* dtlsSrtpProfiles = NULL; #endif ((func_args*)args)->return_code = -1; /* error state */ @@ -1602,13 +1602,13 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif break; - #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) + #ifdef WOLFSSL_SRTP case 260: doDTLS = 1; dtlsUDP = 1; - dtlsSrtpProfile = myoptarg != NULL ? myoptarg : + dtlsSrtpProfiles = myoptarg != NULL ? myoptarg : "SRTP_AES128_CM_SHA1_80"; - printf("Using SRTP Profile: %s\n", dtlsSrtpProfile); + printf("Using SRTP Profile(s): %s\n", dtlsSrtpProfiles); break; #endif @@ -2220,9 +2220,9 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_DEFAULT, NULL); #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) - if (dtlsSrtpProfile != NULL) { - if (wolfSSL_CTX_set_tlsext_use_srtp(ctx, dtlsSrtpProfile) +#ifdef WOLFSSL_SRTP + if (dtlsSrtpProfiles != NULL) { + if (wolfSSL_CTX_set_tlsext_use_srtp(ctx, dtlsSrtpProfiles) != WOLFSSL_SUCCESS) { err_sys_ex(catastrophic, "unable to set DTLS SRTP profile"); } diff --git a/src/internal.c b/src/internal.c index 15aed908a..363c76d1a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -500,11 +500,11 @@ int IsDtlsNotSctpMode(WOLFSSL* ssl) /* Secure Real-time Transport Protocol */ /* If SRTP is not enabled returns the state of the dtls option. - * If SRTP is enabled returns dtls && !dtlsSrtpProfile. */ + * If SRTP is enabled returns dtls && !dtlsSrtpProfiles. */ int IsDtlsNotSrtpMode(WOLFSSL* ssl) { #ifdef WOLFSSL_SRTP - return ssl->options.dtls && !ssl->dtlsSrtpProfile; + return ssl->options.dtls && !ssl->dtlsSrtpProfiles; #else return ssl->options.dtls; #endif @@ -6412,7 +6412,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->options.dtlsSctp = ctx->dtlsSctp; #endif #ifdef WOLFSSL_SRTP - ssl->dtlsSrtpProfile = ctx->dtlsSrtpProfile; + ssl->dtlsSrtpProfiles = ctx->dtlsSrtpProfiles; #endif #if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU) ssl->dtlsMtuSz = ctx->dtlsMtuSz; @@ -17294,7 +17294,7 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr) if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) ssl->buffers.inputBuffer.idx += ssl->specs.block_size; #endif - /* go past TLSv1.1 IV */ + /* go past TLSv1.1 IV */ if (CipherHasExpIV(ssl)) ssl->buffers.inputBuffer.idx += AESGCM_EXP_IV_SZ; #endif diff --git a/src/ssl.c b/src/ssl.c index 99f3034f2..a26198519 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1277,15 +1277,29 @@ int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu) #endif /* WOLFSSL_DTLS && (WOLFSSL_SCTP || WOLFSSL_DTLS_MTU) */ -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP static const WOLFSSL_SRTP_PROTECTION_PROFILE gSrtpProfiles[] = { - /* AES CCM 128, Salt:112-bits, HMAC-SHA1, Tag:80 bits */ - {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80} + /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 80-bits + * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */ + {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80, (((128 + 112) * 2) / 8) }, + /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 32-bits + * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */ + {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32, (((128 + 112) * 2) / 8) }, + /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 80-bits */ + {"SRTP_NULL_SHA1_80", SRTP_NULL_SHA1_80, ((112 * 2) / 8)}, + /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 32-bits */ + {"SRTP_NULL_SHA1_32", SRTP_NULL_SHA1_32, ((112 * 2) / 8)}, + /* AES GCM 128, Salt: 96-bits, Auth GCM Tag 128-bits + * (master_key:128bits + master_salt:96bits) * 2 = 480 bits (60) */ + {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, (((128 + 96) * 2) / 8) }, + /* AES GCM 256, Salt: 96-bits, Auth GCM Tag 128-bits + * (master_key:256bits + master_salt:96bits) * 2 = 480 bits (60) */ + {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, (((256 + 96) * 2) / 8) }, }; -static const WOLFSSL_SRTP_PROTECTION_PROFILE* FindDtlsSrtpProfile( - const char* profile_str, unsigned long id) +static const WOLFSSL_SRTP_PROTECTION_PROFILE* DtlsSrtpFindProfile( + const char* profile_str, word32 profile_str_len, unsigned long id) { int i; const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL; @@ -1293,7 +1307,8 @@ static const WOLFSSL_SRTP_PROTECTION_PROFILE* FindDtlsSrtpProfile( i<(int)(sizeof(gSrtpProfiles)/sizeof(WOLFSSL_SRTP_PROTECTION_PROFILE)); i++) { if (profile_str != NULL) { - if (XSTRCMP(gSrtpProfiles[i].name, profile_str) == 0) { + if (XMEMCMP(gSrtpProfiles[i].name, profile_str, profile_str_len) + == 0) { profile = &gSrtpProfiles[i]; break; } @@ -1305,14 +1320,43 @@ static const WOLFSSL_SRTP_PROTECTION_PROFILE* FindDtlsSrtpProfile( } return profile; } + +/* profile_str: accepts ":" colon separated list of SRTP profiles */ +static int DtlsSrtpSelProfiles(word16* id, const char* profile_str) +{ + const WOLFSSL_SRTP_PROTECTION_PROFILE* profile; + const char *current, *next = NULL; + word32 length = 0, current_length; + + *id = 0; /* reset destination ID's */ + + if (profile_str == NULL) { + return WOLFSSL_FAILURE; + } + + /* loop on end of line or colon ":" */ + next = profile_str; + length = (word32)XSTRLEN(profile_str); + do { + current = next; + next = XSTRSTR(current, ":"); + current_length = (!next) ? (word32)XSTRLEN(current) + : (word32)(next - current); + if (current_length < length) + length = current_length; + profile = DtlsSrtpFindProfile(current, current_length, 0); + if (profile != NULL) { + *id |= (1 << profile->id); /* selected bit based on ID */ + } + } while (next != NULL && next++); /* ++ needed to skip ':' */ + return WOLFSSL_SUCCESS; +} + int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str) { int ret = WOLFSSL_FAILURE; if (ctx != NULL) { - const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = - FindDtlsSrtpProfile(profile_str, 0); - ctx->dtlsSrtpProfile = profile != NULL ? profile->id : 0; - ret = WOLFSSL_SUCCESS; + ret = DtlsSrtpSelProfiles(&ctx->dtlsSrtpProfiles, profile_str); } return ret; } @@ -1320,49 +1364,68 @@ int wolfSSL_set_tlsext_use_srtp(WOLFSSL* ssl, const char* profile_str) { int ret = WOLFSSL_FAILURE; if (ssl != NULL) { - const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = - FindDtlsSrtpProfile(profile_str, 0); - ssl->dtlsSrtpProfile = profile != NULL ? profile->id : 0; - ret = WOLFSSL_SUCCESS; + ret = DtlsSrtpSelProfiles(&ssl->dtlsSrtpProfiles, profile_str); } return ret; } -const WOLFSSL_SRTP_PROTECTION_PROFILE* wolfSSL_get_selected_srtp_profile(WOLFSSL* ssl) +const WOLFSSL_SRTP_PROTECTION_PROFILE* wolfSSL_get_selected_srtp_profile( + WOLFSSL* ssl) { const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL; if (ssl) { - profile = FindDtlsSrtpProfile(NULL, ssl->dtlsSrtpProfile); + profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId); } return profile; } +#ifndef NO_WOLFSSL_STUB +WOLF_STACK_OF(WOLFSSL_SRTP_PROTECTION_PROFILE)* wolfSSL_get_srtp_profiles( + WOLFSSL* ssl) +{ + /* Not yet implemented - should return list of available SRTP profiles + * ssl->dtlsSrtpProfiles */ + (void)ssl; + return NULL; +} +#endif int wolfSSL_export_dtls_srtp_keying_material(WOLFSSL* ssl, unsigned char* out, size_t* olen) { - int ret = WOLFSSL_FAILURE; - const char* label = "EXTRACTOR-dtls_srtp"; + int ret = WOLFSSL_FAILURE; + const char* label = "EXTRACTOR-dtls_srtp"; + const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL; + byte seed[SEED_LEN]; - /* (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */ - size_t length = (128 + (112 * 2)) / 8; + if (ssl == NULL || olen == NULL) { + return BAD_FUNC_ARG; + } - if (ssl == NULL || out == NULL || olen == NULL || *olen < length) { - return BAD_FUNC_ARG; + profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId); + if (profile == NULL) { + WOLFSSL_MSG("Not using DTLS SRTP"); + return EXT_MISSING; + } + if (*olen < (size_t)profile->kdfBits) { + return BUFFER_E; + } + if (out == NULL) { + *olen = profile->kdfBits; + return LENGTH_ONLY_E; } #ifdef WOLFSSL_HAVE_PRF - /* pass the seed via the output (it gets copied out first) */ - XMEMCPY(out, ssl->arrays->serverRandom, RAN_LEN); - XMEMCPY(out + RAN_LEN, ssl->arrays->clientRandom, RAN_LEN); + XMEMCPY(seed, ssl->arrays->serverRandom, RAN_LEN); + XMEMCPY(seed + RAN_LEN, ssl->arrays->clientRandom, RAN_LEN); PRIVATE_KEY_UNLOCK(); - ret = wc_PRF_TLSv1(out, (word32)length, + ret = wc_PRF_TLSv1(out, profile->kdfBits, /* out: generated keys / salt */ ssl->arrays->masterSecret, SECRET_LEN, /* existing master secret */ (const byte*)label, (int)XSTRLEN(label),/* label */ - out, SEED_LEN, /* seed = client/server random */ + seed, SEED_LEN, /* seed: client/server random */ ssl->heap, INVALID_DEVID); if (ret == 0) { - *olen = length; + *olen = profile->kdfBits; ret = WOLFSSL_SUCCESS; } PRIVATE_KEY_LOCK(); @@ -1374,7 +1437,7 @@ int wolfSSL_export_dtls_srtp_keying_material(WOLFSSL* ssl, return ret; } -#endif /* WOLFSSL_DTLS && WOLFSSL_SRTP */ +#endif /* WOLFSSL_SRTP */ #ifdef WOLFSSL_DTLS_DROP_STATS diff --git a/src/tls.c b/src/tls.c index 1660e877a..cfa1fa6d6 100644 --- a/src/tls.c +++ b/src/tls.c @@ -5352,7 +5352,7 @@ int TLSX_EncryptThenMac_Respond(WOLFSSL* ssl) #endif /* HAVE_ENCRYPT_THEN_MAC && !WOLFSSL_AEAD_ONLY */ -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP /******************************************************************************/ /* DTLS SRTP (Secure Real-time Transport Protocol) */ @@ -5360,32 +5360,37 @@ int TLSX_EncryptThenMac_Respond(WOLFSSL* ssl) /* Only support single SRTP profile */ typedef struct TlsxSrtp { - word16 len; - word16 id; + word16 profileCount; + word16 ids; /* selected bits */ } TlsxSrtp; static int TLSX_UseSRTP_GetSize(TlsxSrtp *srtp) { - /* only supports single profile */ - const int profileCount = 1; - (void)srtp; /* SRTP Profile Len (2) * SRTP Profiles (2) * MKI (master key id) Length */ - return (OPAQUE16_LEN + (profileCount * OPAQUE16_LEN) + 1); + return (OPAQUE16_LEN + (srtp->profileCount * OPAQUE16_LEN) + 1); } -static TlsxSrtp* TLSX_UseSRTP_New(word16 id, void* heap) +static TlsxSrtp* TLSX_UseSRTP_New(word16 ids, void* heap) { TlsxSrtp* srtp; + int i; srtp = (TlsxSrtp*)XMALLOC(sizeof(TlsxSrtp), heap, DYNAMIC_TYPE_TLSX); if (srtp == NULL) { WOLFSSL_MSG("TLSX SRTP Memory failure"); return NULL; } - srtp->len = 2; - srtp->id = id; + + /* count and test each bit set */ + srtp->profileCount = 0; + for (i=0; i<16; i++) { + if (ids & (1 << i)) { + srtp->profileCount++; + } + } + srtp->ids = ids; return srtp; } @@ -5416,7 +5421,7 @@ static int TLSX_UseSRTP_Parse(WOLFSSL* ssl, const byte* input, word16 length, if (!isRequest) { #ifndef NO_WOLFSSL_CLIENT - ssl->dtlsSrtpProfile = ssl->ctx->dtlsSrtpProfile; + ssl->dtlsSrtpProfiles = ssl->ctx->dtlsSrtpProfiles; ret = 0; /* success */ #endif } @@ -5428,10 +5433,13 @@ static int TLSX_UseSRTP_Parse(WOLFSSL* ssl, const byte* input, word16 length, /* parse remainder one profile at a time, looking for match in CTX */ for (i=offset; ictx->dtlsSrtpProfile) { - ssl->dtlsSrtpProfile = profile_value; + /* find first match */ + if (profile_value < 16 && + ssl->dtlsSrtpProfiles & (1 << profile_value)) { + ssl->dtlsSrtpId = profile_value; - srtp = TLSX_UseSRTP_New(profile_value, ssl->heap); + /* make sure we respond with selected SRTP id selected */ + srtp = TLSX_UseSRTP_New((1 << profile_value), ssl->heap); if (srtp != NULL) { ret = TLSX_Push(&ssl->extensions, TLSX_USE_SRTP, (void*)srtp, ssl->heap); @@ -5442,14 +5450,18 @@ static int TLSX_UseSRTP_Parse(WOLFSSL* ssl, const byte* input, word16 length, else { ret = MEMORY_E; } + break; } } (void)profile_len; } if (ret != 0) { - ssl->dtlsSrtpProfile = 0; + WOLFSSL_MSG("SRP Profile not found!"); + ssl->dtlsSrtpId = 0; TLSX_UseSRTP_Free(srtp, ssl->heap); + /* not fatal, so return 0 */ + ret = 0; } #endif @@ -5459,17 +5471,24 @@ static int TLSX_UseSRTP_Parse(WOLFSSL* ssl, const byte* input, word16 length, static word16 TLSX_UseSRTP_Write(TlsxSrtp* srtp, byte* output) { word16 offset = 0; + int i, j; - c16toa(srtp->len, output+offset); + c16toa(srtp->profileCount*2, output+offset); offset += OPAQUE16_LEN; - c16toa(srtp->id, output+offset); - offset += srtp->len; + for (i=0; i< srtp->profileCount; i+=2) { + for (j=0; j<16; j++) { + if (srtp->ids & (1 << j)) { + c16toa(j, output+offset); + offset += OPAQUE16_LEN; + } + } + } output[offset++] = 0x00; /* MKI Length */ return offset; } -static int TLSX_UseSRTP(TLSX** extensions, word16 profile_value, void* heap) +static int TLSX_UseSRTP(TLSX** extensions, word16 profiles, void* heap) { int ret = 0; TlsxSrtp *srtp = NULL; @@ -5479,7 +5498,7 @@ static int TLSX_UseSRTP(TLSX** extensions, word16 profile_value, void* heap) return BAD_FUNC_ARG; } - srtp = TLSX_UseSRTP_New(profile_value, heap); + srtp = TLSX_UseSRTP_New(profiles, heap); if (srtp == NULL) { return MEMORY_E; } @@ -5507,7 +5526,7 @@ static int TLSX_UseSRTP(TLSX** extensions, word16 profile_value, void* heap) #define SRTP_GET_SIZE(a) 0 #endif -#endif /* WOLFSSL_DTLS && WOLFSSL_SRTP */ +#endif /* WOLFSSL_SRTP */ /******************************************************************************/ @@ -9789,7 +9808,7 @@ void TLSX_FreeAll(TLSX* list, void* heap) KS_FREE_ALL((KeyShareEntry*)extension->data, heap); break; #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP case TLSX_USE_SRTP: SRTP_FREE((TlsxSrtp*)extension->data, heap); break; @@ -9945,7 +9964,7 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType, length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType); break; #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP case TLSX_USE_SRTP: length += SRTP_GET_SIZE((TlsxSrtp*)extension->data); break; @@ -10133,7 +10152,7 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore, output + offset, msgType); break; #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP case TLSX_USE_SRTP: offset += SRTP_WRITE((TlsxSrtp*)extension->data, output+offset); break; @@ -10513,18 +10532,17 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) return ret; } #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */ - } /* is not server */ -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) - if (ssl->options.dtls && ssl->dtlsSrtpProfile != 0) { - WOLFSSL_MSG("Adding DTLS SRTP extension"); - if ((ret = TLSX_UseSRTP(&ssl->extensions, ssl->dtlsSrtpProfile, - ssl->heap)) != 0) { - return ret; +#ifdef WOLFSSL_SRTP + if (ssl->options.dtls && ssl->dtlsSrtpProfiles != 0) { + WOLFSSL_MSG("Adding DTLS SRTP extension"); + if ((ret = TLSX_UseSRTP(&ssl->extensions, ssl->dtlsSrtpProfiles, + ssl->heap)) != 0) { + return ret; + } } - } - #endif + } /* is not server */ #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG) WOLFSSL_MSG("Adding signature algorithms extension"); @@ -11748,7 +11766,7 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType, ret = KS_PARSE(ssl, input + offset, size, msgType); break; #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP case TLSX_USE_SRTP: WOLFSSL_MSG("Use SRTP extension received"); ret = SRTP_PARSE(ssl, input + offset, size, isRequest); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 7d7bafb6d..6189a06f5 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2285,7 +2285,7 @@ typedef enum { #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG) TLSX_SIGNATURE_ALGORITHMS = 0x000d, /* HELLO_EXT_SIG_ALGO */ #endif -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP TLSX_USE_SRTP = 0x000e, /* 14 */ #endif TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */ @@ -2864,8 +2864,9 @@ struct WOLFSSL_CTX { word16 minProto:1; /* sets min to min available */ word16 maxProto:1; /* sets max to max available */ -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) - word16 dtlsSrtpProfile; /* DTLS-with-SRTP mode */ +#ifdef WOLFSSL_SRTP + word16 dtlsSrtpProfiles; /* DTLS-with-SRTP mode + * (list of selected profiles - up to 16) */ #endif #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_MULTICAST) byte haveMcast; /* multicast requested */ @@ -4408,7 +4409,9 @@ struct WOLFSSL { word32 replayDropCount; #endif /* WOLFSSL_DTLS_DROP_STATS */ #ifdef WOLFSSL_SRTP - word16 dtlsSrtpProfile; /* DTLS-with-SRTP mode */ + word16 dtlsSrtpProfiles; /* DTLS-with-SRTP profiles list + * (selected profiles - up to 16) */ + word16 dtlsSrtpId; /* DTLS-with-SRTP profile ID selected */ #endif #endif /* WOLFSSL_DTLS */ #ifdef WOLFSSL_CALLBACKS diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 39a8c5c72..39a9f972c 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -331,7 +331,6 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; /* wolfSSL does not support security levels */ #define SSL_CTX_set_security_level wolfSSL_CTX_set_security_level #define SSL_CTX_get_security_level wolfSSL_CTX_get_security_level -/* wolfSSL does not support exporting keying material */ #define SSL_export_keying_material wolfSSL_export_keying_material #define SSL_CTX_set1_sigalgs_list wolfSSL_CTX_set1_sigalgs_list @@ -1081,13 +1080,13 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define DTLSv1_set_initial_timeout_duration wolfSSL_DTLSv1_set_initial_timeout_duration /* DTLS SRTP */ -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE; #endif #define SSL_CTX_set_tlsext_use_srtp wolfSSL_CTX_set_tlsext_use_srtp #define SSL_set_tlsext_use_srtp wolfSSL_set_tlsext_use_srtp #define SSL_get_selected_srtp_profile wolfSSL_get_selected_srtp_profile -#define SSL_export_dtls_srtp_keying_material wolfSSL_export_dtls_srtp_keying_material +#define SSL_get_srtp_profiles wolfSSL_get_srtp_profiles #ifndef NO_WOLFSSL_STUB #define SSL_CTX_set_current_time_cb(ssl, cb) ({ (void)ssl; (void)cb; }) diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 5e6ff1f41..2a1ad45aa 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1292,15 +1292,15 @@ WOLFSSL_API int wolfSSL_dtls_set_sctp(WOLFSSL*); WOLFSSL_API int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX*, unsigned short); WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned short); -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SRTP) +#ifdef WOLFSSL_SRTP -/* SRTP Profile ID's */ -/* NOTE: we only support the SRTP_AES128_CM_SHA1_80 profile - * (as required by draft-ietf-rtcweb-security-arch) */ +/* SRTP Profile ID's from RFC 5764 and RFC 7714 */ +/* For WebRTC support for profile SRTP_AES128_CM_SHA1_80 is required per + * draft-ietf-rtcweb-security-arch) */ #define SRTP_AES128_CM_SHA1_80 0x0001 #define SRTP_AES128_CM_SHA1_32 0x0002 -#define SRTP_AES128_F8_SHA1_80 0x0003 -#define SRTP_AES128_F8_SHA1_32 0x0004 +#define SRTP_AES128_F8_SHA1_80 0x0003 /* not supported */ +#define SRTP_AES128_F8_SHA1_32 0x0004 /* not supported */ #define SRTP_NULL_SHA1_80 0x0005 #define SRTP_NULL_SHA1_32 0x0006 #define SRTP_AEAD_AES_128_GCM 0x0007 @@ -1309,15 +1309,21 @@ WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned short); typedef struct WOLFSSL_SRTP_PROTECTION_PROFILE { const char* name; unsigned long id; + int kdfBits; } WOLFSSL_SRTP_PROTECTION_PROFILE; +/* Compatibility API's for SRTP */ WOLFSSL_API int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX*, const char*); WOLFSSL_API int wolfSSL_set_tlsext_use_srtp(WOLFSSL*, const char*); WOLFSSL_API const WOLFSSL_SRTP_PROTECTION_PROFILE* wolfSSL_get_selected_srtp_profile(WOLFSSL*); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_SRTP_PROTECTION_PROFILE)* + wolfSSL_get_srtp_profiles(WOLFSSL*); + +/* Non standard API for getting the SRTP session keys using KDF */ WOLFSSL_API int wolfSSL_export_dtls_srtp_keying_material(WOLFSSL*, unsigned char*, size_t*); -#endif /* WOLFSSL_DTLS && WOLFSSL_SRTP */ +#endif /* WOLFSSL_SRTP */ WOLFSSL_API int wolfSSL_dtls_get_drop_stats(WOLFSSL*, unsigned int*, unsigned int*); diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index c68b17915..4f863cfee 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2436,7 +2436,8 @@ extern void uITRON4_free(void *p) ; #define WOLFSSL_NO_WORD64_OPS #endif -#if !defined(WOLFCRYPT_ONLY) && !defined(WOLFSSL_NO_TLS12) +#if !defined(WOLFCRYPT_ONLY) && \ + (!defined(WOLFSSL_NO_TLS12) || defined(HAVE_KEYING_MATERIAL)) #undef WOLFSSL_HAVE_PRF #define WOLFSSL_HAVE_PRF #endif @@ -2607,6 +2608,14 @@ extern void uITRON4_free(void *p) ; #error "You must have a post-quantum cryptography implementation to use PQC." #endif + +/* SRTP requires DTLS */ +#if defined(WOLFSSL_SRTP) && !defined(WOLFSSL_DTLS) + #error The SRTP extension requires DTLS +#endif + + + /* --------------------------------------------------------------------------- * Depricated Algorithm Handling * Unless allowed via a build macro, disable support