srtcp.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package srtp
  4. import (
  5. "encoding/binary"
  6. "fmt"
  7. "github.com/pion/rtcp"
  8. )
  9. const maxSRTCPIndex = 0x7FFFFFFF
  10. func (c *Context) decryptRTCP(dst, encrypted []byte) ([]byte, error) {
  11. out := allocateIfMismatch(dst, encrypted)
  12. authTagLen, err := c.cipher.rtcpAuthTagLen()
  13. if err != nil {
  14. return nil, err
  15. }
  16. aeadAuthTagLen, err := c.cipher.aeadAuthTagLen()
  17. if err != nil {
  18. return nil, err
  19. }
  20. tailOffset := len(encrypted) - (authTagLen + srtcpIndexSize)
  21. if tailOffset < aeadAuthTagLen {
  22. return nil, fmt.Errorf("%w: %d", errTooShortRTCP, len(encrypted))
  23. } else if isEncrypted := encrypted[tailOffset] >> 7; isEncrypted == 0 {
  24. return out, nil
  25. }
  26. index := c.cipher.getRTCPIndex(encrypted)
  27. ssrc := binary.BigEndian.Uint32(encrypted[4:])
  28. s := c.getSRTCPSSRCState(ssrc)
  29. markAsValid, ok := s.replayDetector.Check(uint64(index))
  30. if !ok {
  31. return nil, &duplicatedError{Proto: "srtcp", SSRC: ssrc, Index: index}
  32. }
  33. out, err = c.cipher.decryptRTCP(out, encrypted, index, ssrc)
  34. if err != nil {
  35. return nil, err
  36. }
  37. markAsValid()
  38. return out, nil
  39. }
  40. // DecryptRTCP decrypts a buffer that contains a RTCP packet
  41. func (c *Context) DecryptRTCP(dst, encrypted []byte, header *rtcp.Header) ([]byte, error) {
  42. if header == nil {
  43. header = &rtcp.Header{}
  44. }
  45. if err := header.Unmarshal(encrypted); err != nil {
  46. return nil, err
  47. }
  48. return c.decryptRTCP(dst, encrypted)
  49. }
  50. func (c *Context) encryptRTCP(dst, decrypted []byte) ([]byte, error) {
  51. ssrc := binary.BigEndian.Uint32(decrypted[4:])
  52. s := c.getSRTCPSSRCState(ssrc)
  53. if s.srtcpIndex >= maxSRTCPIndex {
  54. // ... when 2^48 SRTP packets or 2^31 SRTCP packets have been secured with the same key
  55. // (whichever occurs before), the key management MUST be called to provide new master key(s)
  56. // (previously stored and used keys MUST NOT be used again), or the session MUST be terminated.
  57. // https://www.rfc-editor.org/rfc/rfc3711#section-9.2
  58. return nil, errExceededMaxPackets
  59. }
  60. // We roll over early because MSB is used for marking as encrypted
  61. s.srtcpIndex++
  62. return c.cipher.encryptRTCP(dst, decrypted, s.srtcpIndex, ssrc)
  63. }
  64. // EncryptRTCP Encrypts a RTCP packet
  65. func (c *Context) EncryptRTCP(dst, decrypted []byte, header *rtcp.Header) ([]byte, error) {
  66. if header == nil {
  67. header = &rtcp.Header{}
  68. }
  69. if err := header.Unmarshal(decrypted); err != nil {
  70. return nil, err
  71. }
  72. return c.encryptRTCP(dst, decrypted)
  73. }