From a717d6f0a198fdbd9ea99235faf7cdcc0deea3cf Mon Sep 17 00:00:00 2001 From: sirzooro Date: Sun, 7 Jul 2024 15:28:56 +0200 Subject: [PATCH] New SRTP cipher test suite Moved tests from srtp_cipher_aead_aes_gcm_test.go to new file, cleaned up their code to make it more DRY. Added tests for AES CM ciphers there too. This new cipher test suite will make it easier to add tests for new SRTP features without lots of copy/paste. --- protection_profile.go | 15 +++ srtp_cipher_aead_aes_gcm_test.go | 164 --------------------------- srtp_cipher_test.go | 187 +++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+), 164 deletions(-) delete mode 100644 srtp_cipher_aead_aes_gcm_test.go create mode 100644 srtp_cipher_test.go diff --git a/protection_profile.go b/protection_profile.go index c9b0fce..9f3a2d4 100644 --- a/protection_profile.go +++ b/protection_profile.go @@ -84,3 +84,18 @@ func (p ProtectionProfile) authKeyLen() (int, error) { return 0, fmt.Errorf("%w: %#v", errNoSuchSRTPProfile, p) } } + +func (p ProtectionProfile) String() string { + switch p { + case ProtectionProfileAes128CmHmacSha1_80: + return "SRTP_AES128_CM_HMAC_SHA1_80" + case ProtectionProfileAes128CmHmacSha1_32: + return "SRTP_AES128_CM_HMAC_SHA1_32" + case ProtectionProfileAeadAes128Gcm: + return "SRTP_AEAD_AES_128_GCM" + case ProtectionProfileAeadAes256Gcm: + return "SRTP_AEAD_AES_256_GCM" + default: + return fmt.Sprintf("Unknown SRTP profile: %#v", p) + } +} diff --git a/srtp_cipher_aead_aes_gcm_test.go b/srtp_cipher_aead_aes_gcm_test.go deleted file mode 100644 index 90fd88c..0000000 --- a/srtp_cipher_aead_aes_gcm_test.go +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestSrtpCipherAedAes128Gcm(t *testing.T) { - decryptedRTPPacket := []byte{ - 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, - 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, - } - encryptedRTPPacket := []byte{ - 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, - 0xca, 0xfe, 0xba, 0xbe, 0xc5, 0x00, 0x2e, 0xde, - 0x04, 0xcf, 0xdd, 0x2e, 0xb9, 0x11, 0x59, 0xe0, - 0x88, 0x0a, 0xa0, 0x6e, 0xd2, 0x97, 0x68, 0x26, - 0xf7, 0x96, 0xb2, 0x01, 0xdf, 0x31, 0x31, 0xa1, - 0x27, 0xe8, 0xa3, 0x92, - } - decryptedRtcpPacket := []byte{ - 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - } - encryptedRtcpPacket := []byte{ - 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, - 0xc9, 0x8b, 0x8b, 0x5d, 0xf0, 0x39, 0x2a, 0x55, - 0x85, 0x2b, 0x6c, 0x21, 0xac, 0x8e, 0x70, 0x25, - 0xc5, 0x2c, 0x6f, 0xbe, 0xa2, 0xb3, 0xb4, 0x46, - 0xea, 0x31, 0x12, 0x3b, 0xa8, 0x8c, 0xe6, 0x1e, - 0x80, 0x00, 0x00, 0x01, - } - - masterKey := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f} - masterSalt := []byte{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab} - - t.Run("Encrypt RTP", func(t *testing.T) { - ctx, err := CreateContext(masterKey, masterSalt, ProtectionProfileAeadAes128Gcm) - assert.NoError(t, err) - - t.Run("New Allocation", func(t *testing.T) { - actualEncrypted, err := ctx.EncryptRTP(nil, decryptedRTPPacket, nil) - assert.NoError(t, err) - assert.Equal(t, encryptedRTPPacket, actualEncrypted) - }) - }) - - t.Run("Decrypt RTP", func(t *testing.T) { - ctx, err := CreateContext(masterKey, masterSalt, ProtectionProfileAeadAes128Gcm) - assert.NoError(t, err) - - t.Run("New Allocation", func(t *testing.T) { - actualDecrypted, err := ctx.DecryptRTP(nil, encryptedRTPPacket, nil) - assert.NoError(t, err) - assert.Equal(t, decryptedRTPPacket, actualDecrypted) - }) - }) - - t.Run("Encrypt RTCP", func(t *testing.T) { - ctx, err := CreateContext(masterKey, masterSalt, ProtectionProfileAeadAes128Gcm) - assert.NoError(t, err) - - t.Run("New Allocation", func(t *testing.T) { - actualEncrypted, err := ctx.EncryptRTCP(nil, decryptedRtcpPacket, nil) - assert.NoError(t, err) - assert.Equal(t, encryptedRtcpPacket, actualEncrypted) - }) - }) - - t.Run("Decrypt RTCP", func(t *testing.T) { - ctx, err := CreateContext(masterKey, masterSalt, ProtectionProfileAeadAes128Gcm) - assert.NoError(t, err) - - t.Run("New Allocation", func(t *testing.T) { - actualDecrypted, err := ctx.DecryptRTCP(nil, encryptedRtcpPacket, nil) - assert.NoError(t, err) - assert.Equal(t, decryptedRtcpPacket, actualDecrypted) - }) - }) -} - -func TestSrtpCipherAedAes256Gcm(t *testing.T) { - decryptedRTPPacket := []byte{ - 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, - 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, - } - encryptedRTPPacket := []byte{ - 0x80, 0xf, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, - 0xca, 0xfe, 0xba, 0xbe, 0xaf, 0x49, 0x96, 0x8f, - 0x7e, 0x9c, 0x43, 0xf8, 0x01, 0xdd, 0x0c, 0x84, - 0x8b, 0x1e, 0xc9, 0xb0, 0x29, 0xcd, 0xf8, 0x5c, - 0xb7, 0x9a, 0x2f, 0x95, 0x60, 0xd4, 0x69, 0x75, - 0x98, 0x50, 0x77, 0x25, - } - decryptedRtcpPacket := []byte{ - 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - } - encryptedRtcpPacket := []byte{ - 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, - 0x98, 0x22, 0xba, 0x22, 0x96, 0x1c, 0x31, 0x48, - 0xe7, 0xb7, 0xec, 0x4f, 0x09, 0xf4, 0x26, 0xdc, - 0xf6, 0xb5, 0x9a, 0x75, 0xad, 0xec, 0x74, 0xfd, - 0xb9, 0x51, 0xb6, 0x66, 0x84, 0x24, 0xd4, 0xe2, - 0x80, 0x00, 0x00, 0x01, - } - - masterKey := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f} - masterSalt := []byte{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab} - - t.Run("Encrypt RTP", func(t *testing.T) { - ctx, err := CreateContext(masterKey, masterSalt, ProtectionProfileAeadAes256Gcm) - assert.NoError(t, err) - - t.Run("New Allocation", func(t *testing.T) { - actualEncrypted, err := ctx.EncryptRTP(nil, decryptedRTPPacket, nil) - assert.NoError(t, err) - assert.Equal(t, encryptedRTPPacket, actualEncrypted) - }) - }) - - t.Run("Decrypt RTP", func(t *testing.T) { - ctx, err := CreateContext(masterKey, masterSalt, ProtectionProfileAeadAes256Gcm) - assert.NoError(t, err) - - t.Run("New Allocation", func(t *testing.T) { - actualDecrypted, err := ctx.DecryptRTP(nil, encryptedRTPPacket, nil) - assert.NoError(t, err) - assert.Equal(t, decryptedRTPPacket, actualDecrypted) - }) - }) - - t.Run("Encrypt RTCP", func(t *testing.T) { - ctx, err := CreateContext(masterKey, masterSalt, ProtectionProfileAeadAes256Gcm) - assert.NoError(t, err) - - t.Run("New Allocation", func(t *testing.T) { - actualEncrypted, err := ctx.EncryptRTCP(nil, decryptedRtcpPacket, nil) - assert.NoError(t, err) - assert.Equal(t, encryptedRtcpPacket, actualEncrypted) - }) - }) - - t.Run("Decrypt RTCP", func(t *testing.T) { - ctx, err := CreateContext(masterKey, masterSalt, ProtectionProfileAeadAes256Gcm) - assert.NoError(t, err) - - t.Run("New Allocation", func(t *testing.T) { - actualDecrypted, err := ctx.DecryptRTCP(nil, encryptedRtcpPacket, nil) - assert.NoError(t, err) - assert.Equal(t, decryptedRtcpPacket, actualDecrypted) - }) - }) -} diff --git a/srtp_cipher_test.go b/srtp_cipher_test.go new file mode 100644 index 0000000..d45907e --- /dev/null +++ b/srtp_cipher_test.go @@ -0,0 +1,187 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package srtp + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type testCipher struct { + profile ProtectionProfile // Protection profile + masterKey []byte // Master key + masterSalt []byte // Master salt + + decryptedRTPPacket []byte + encryptedRTPPacket []byte + decryptedRTCPPacket []byte + encryptedRTCPPacket []byte +} + +// create array of testCiphers for each supported profile +func createTestCiphers() []testCipher { + tests := []testCipher{ + { + profile: ProtectionProfileAes128CmHmacSha1_32, + encryptedRTPPacket: []byte{ + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xe2, 0xd8, 0xdf, 0x8f, + 0x7a, 0x75, 0xd6, 0x88, 0xc3, 0x50, 0x2e, 0xee, + 0xc2, 0xa9, 0x80, 0x66, 0xcd, 0x7c, 0x0d, 0x09, + }, + encryptedRTCPPacket: []byte{ + 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, + 0x56, 0x74, 0xbf, 0x01, 0x81, 0x3d, 0xc0, 0x62, + 0xac, 0x1d, 0xf6, 0xf7, 0x5f, 0x77, 0xc6, 0x88, + 0x80, 0x00, 0x00, 0x01, 0x3d, 0xb7, 0xa1, 0x98, + 0x37, 0xff, 0x64, 0xe5, 0xcb, 0xd2, + }, + }, + { + profile: ProtectionProfileAes128CmHmacSha1_80, + encryptedRTPPacket: []byte{ + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xe2, 0xd8, 0xdf, 0x8f, + 0x7a, 0x75, 0xd6, 0x88, 0xc3, 0x50, 0x2e, 0xee, + 0xc2, 0xa9, 0x80, 0x66, 0xcd, 0x7c, 0x0d, 0x09, + 0xca, 0x44, 0x32, 0xa5, 0x6e, 0x3d, + }, + encryptedRTCPPacket: []byte{ + 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, + 0x56, 0x74, 0xbf, 0x01, 0x81, 0x3d, 0xc0, 0x62, + 0xac, 0x1d, 0xf6, 0xf7, 0x5f, 0x77, 0xc6, 0x88, + 0x80, 0x00, 0x00, 0x01, 0x3d, 0xb7, 0xa1, 0x98, + 0x37, 0xff, 0x64, 0xe5, 0xcb, 0xd2, + }, + }, + { + profile: ProtectionProfileAeadAes128Gcm, + encryptedRTPPacket: []byte{ + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xc5, 0x00, 0x2e, 0xde, + 0x04, 0xcf, 0xdd, 0x2e, 0xb9, 0x11, 0x59, 0xe0, + 0x88, 0x0a, 0xa0, 0x6e, 0xd2, 0x97, 0x68, 0x26, + 0xf7, 0x96, 0xb2, 0x01, 0xdf, 0x31, 0x31, 0xa1, + 0x27, 0xe8, 0xa3, 0x92, + }, + encryptedRTCPPacket: []byte{ + 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, + 0xc9, 0x8b, 0x8b, 0x5d, 0xf0, 0x39, 0x2a, 0x55, + 0x85, 0x2b, 0x6c, 0x21, 0xac, 0x8e, 0x70, 0x25, + 0xc5, 0x2c, 0x6f, 0xbe, 0xa2, 0xb3, 0xb4, 0x46, + 0xea, 0x31, 0x12, 0x3b, 0xa8, 0x8c, 0xe6, 0x1e, + 0x80, 0x00, 0x00, 0x01, + }, + }, + { + profile: ProtectionProfileAeadAes256Gcm, + encryptedRTPPacket: []byte{ + 0x80, 0xf, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xaf, 0x49, 0x96, 0x8f, + 0x7e, 0x9c, 0x43, 0xf8, 0x01, 0xdd, 0x0c, 0x84, + 0x8b, 0x1e, 0xc9, 0xb0, 0x29, 0xcd, 0xf8, 0x5c, + 0xb7, 0x9a, 0x2f, 0x95, 0x60, 0xd4, 0x69, 0x75, + 0x98, 0x50, 0x77, 0x25, + }, + encryptedRTCPPacket: []byte{ + 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, + 0x98, 0x22, 0xba, 0x22, 0x96, 0x1c, 0x31, 0x48, + 0xe7, 0xb7, 0xec, 0x4f, 0x09, 0xf4, 0x26, 0xdc, + 0xf6, 0xb5, 0x9a, 0x75, 0xad, 0xec, 0x74, 0xfd, + 0xb9, 0x51, 0xb6, 0x66, 0x84, 0x24, 0xd4, 0xe2, + 0x80, 0x00, 0x00, 0x01, + }, + }, + } + + masterKey := []byte{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + } + masterSalt := []byte{ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0x0ac, 0xad, + } + decryptedRTPPacket := []byte{ + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, + } + decryptedRTCPPacket := []byte{ + 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + } + + for k, v := range tests { + keyLen, err := v.profile.keyLen() + if err != nil { + panic(err) + } + saltLen, err := v.profile.saltLen() + if err != nil { + panic(err) + } + tests[k].masterKey = masterKey[:keyLen] + tests[k].masterSalt = masterSalt[:saltLen] + tests[k].decryptedRTPPacket = decryptedRTPPacket + tests[k].decryptedRTCPPacket = decryptedRTCPPacket + } + + return tests +} + +func TestSrtpCipher(t *testing.T) { + for _, c := range createTestCiphers() { + t.Run(c.profile.String(), func(t *testing.T) { + t.Run("Encrypt RTP", func(t *testing.T) { + ctx, err := CreateContext(c.masterKey, c.masterSalt, c.profile) + assert.NoError(t, err) + + t.Run("New Allocation", func(t *testing.T) { + actualEncrypted, err := ctx.EncryptRTP(nil, c.decryptedRTPPacket, nil) + assert.NoError(t, err) + assert.Equal(t, c.encryptedRTPPacket, actualEncrypted) + }) + }) + + t.Run("Decrypt RTP", func(t *testing.T) { + ctx, err := CreateContext(c.masterKey, c.masterSalt, c.profile) + assert.NoError(t, err) + + t.Run("New Allocation", func(t *testing.T) { + actualDecrypted, err := ctx.DecryptRTP(nil, c.encryptedRTPPacket, nil) + assert.NoError(t, err) + assert.Equal(t, c.decryptedRTPPacket, actualDecrypted) + }) + }) + + t.Run("Encrypt RTCP", func(t *testing.T) { + ctx, err := CreateContext(c.masterKey, c.masterSalt, c.profile) + assert.NoError(t, err) + + t.Run("New Allocation", func(t *testing.T) { + actualEncrypted, err := ctx.EncryptRTCP(nil, c.decryptedRTCPPacket, nil) + assert.NoError(t, err) + assert.Equal(t, c.encryptedRTCPPacket, actualEncrypted) + }) + }) + + t.Run("Decrypt RTCP", func(t *testing.T) { + ctx, err := CreateContext(c.masterKey, c.masterSalt, c.profile) + assert.NoError(t, err) + + t.Run("New Allocation", func(t *testing.T) { + actualDecrypted, err := ctx.DecryptRTCP(nil, c.encryptedRTCPPacket, nil) + assert.NoError(t, err) + assert.Equal(t, c.decryptedRTCPPacket, actualDecrypted) + }) + }) + }) + } +}