srtp.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:22k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*
  2.  * Secure RTP with libgcrypt
  3.  * Copyright (C) 2007  Rémi Denis-Courmont <rdenis # simphalempin , com>
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2.1 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18.  */
  19. /* TODO:
  20.  * Useless stuff (because nothing depends on it):
  21.  * - non-nul key derivation rate
  22.  * - MKI payload
  23.  */
  24. #ifdef HAVE_CONFIG_H
  25. # include <config.h>
  26. #endif
  27. #include <stdint.h>
  28. #include <stddef.h>
  29. #include "srtp.h"
  30. #include <stdbool.h>
  31. #include <stdlib.h>
  32. #include <assert.h>
  33. #include <errno.h>
  34. #include <gcrypt.h>
  35. #ifdef WIN32
  36. # include <winsock2.h>
  37. #else
  38. # include <netinet/in.h>
  39. # include <pthread.h>
  40. GCRY_THREAD_OPTION_PTHREAD_IMPL;
  41. #endif
  42. #define debug( ... ) (void)0
  43. typedef struct srtp_proto_t
  44. {
  45.     gcry_cipher_hd_t cipher;
  46.     gcry_md_hd_t     mac;
  47.     uint64_t         window;
  48.     uint32_t         salt[4];
  49. } srtp_proto_t;
  50. struct srtp_session_t
  51. {
  52.     srtp_proto_t rtp;
  53.     srtp_proto_t rtcp;
  54.     unsigned flags;
  55.     unsigned kdr;
  56.     uint32_t rtcp_index;
  57.     uint32_t rtp_roc;
  58.     uint16_t rtp_seq;
  59.     uint16_t rtp_rcc;
  60.     uint8_t  tag_len;
  61. };
  62. enum
  63. {
  64.     SRTP_CRYPT,
  65.     SRTP_AUTH,
  66.     SRTP_SALT,
  67.     SRTCP_CRYPT,
  68.     SRTCP_AUTH,
  69.     SRTCP_SALT
  70. };
  71. static inline unsigned rcc_mode (const srtp_session_t *s)
  72. {
  73.     return (s->flags >> 4) & 3;
  74. }
  75. static bool libgcrypt_usable = false;
  76. static void initonce_libgcrypt (void)
  77. {
  78. #ifndef WIN32
  79.     gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
  80. #endif
  81.     if ((gcry_check_version ("1.1.94") == NULL)
  82.      || gcry_control (GCRYCTL_DISABLE_SECMEM, 0)
  83.      || gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0))
  84.         return;
  85.     libgcrypt_usable = true;
  86. }
  87. static int init_libgcrypt (void)
  88. {
  89.     int retval;
  90. #ifndef WIN32
  91.     static pthread_once_t once = PTHREAD_ONCE_INIT;
  92.     pthread_once (&once, initonce_libgcrypt);
  93. #else
  94. # warning FIXME: This is not thread-safe.
  95.     if (!libgcrypt_usable)
  96.         initonce_libgcrypt ();
  97. #endif
  98.     retval = libgcrypt_usable ? 0 : -1;
  99.     return retval;
  100. }
  101. static void proto_destroy (srtp_proto_t *p)
  102. {
  103.     gcry_md_close (p->mac);
  104.     gcry_cipher_close (p->cipher);
  105. }
  106. /**
  107.  * Releases all resources associated with a Secure RTP session.
  108.  */
  109. void srtp_destroy (srtp_session_t *s)
  110. {
  111.     assert (s != NULL);
  112.     proto_destroy (&s->rtcp);
  113.     proto_destroy (&s->rtp);
  114.     free (s);
  115. }
  116. static int proto_create (srtp_proto_t *p, int gcipher, int gmd)
  117. {
  118.     if (gcry_cipher_open (&p->cipher, gcipher, GCRY_CIPHER_MODE_CTR, 0) == 0)
  119.     {
  120.         if (gcry_md_open (&p->mac, gmd, GCRY_MD_FLAG_HMAC) == 0)
  121.             return 0;
  122.         gcry_cipher_close (p->cipher);
  123.     }
  124.     return -1;
  125. }
  126. /**
  127.  * Allocates a Secure RTP one-way session.
  128.  * The same session cannot be used both ways because this would confuse
  129.  * internal cryptographic counters; it is however of course feasible to open
  130.  * multiple simultaneous sessions with the same master key.
  131.  *
  132.  * @param encr encryption algorithm number
  133.  * @param auth authentication algortihm number
  134.  * @param tag_len authentication tag byte length (NOT including RCC)
  135.  * @param flags OR'ed optional flags.
  136.  *
  137.  * @return NULL in case of error
  138.  */
  139. srtp_session_t *
  140. srtp_create (int encr, int auth, unsigned tag_len, int prf, unsigned flags)
  141. {
  142.     if ((flags & ~SRTP_FLAGS_MASK) || init_libgcrypt ())
  143.         return NULL;
  144.     int cipher, md;
  145.     switch (encr)
  146.     {
  147.         case SRTP_ENCR_NULL:
  148.             cipher = GCRY_CIPHER_NONE;
  149.             break;
  150.         case SRTP_ENCR_AES_CM:
  151.             cipher = GCRY_CIPHER_AES;
  152.             break;
  153.         default:
  154.             return NULL;
  155.     }
  156.     switch (auth)
  157.     {
  158.         case SRTP_AUTH_NULL:
  159.             md = GCRY_MD_NONE;
  160.             break;
  161.         case SRTP_AUTH_HMAC_SHA1:
  162.             md = GCRY_MD_SHA1;
  163.             break;
  164.         default:
  165.             return NULL;
  166.     }
  167.     if (tag_len > gcry_md_get_algo_dlen (md))
  168.         return NULL;
  169.     if (prf != SRTP_PRF_AES_CM)
  170.         return NULL;
  171.     srtp_session_t *s = malloc (sizeof (*s));
  172.     if (s == NULL)
  173.         return NULL;
  174.     memset (s, 0, sizeof (*s));
  175.     s->flags = flags;
  176.     s->tag_len = tag_len;
  177.     s->rtp_rcc = 1; /* Default RCC rate */
  178.     if (rcc_mode (s))
  179.     {
  180.         if (tag_len < 4)
  181.             goto error;
  182.     }
  183.     if (proto_create (&s->rtp, cipher, md) == 0)
  184.     {
  185.         if (proto_create (&s->rtcp, cipher, md) == 0)
  186.             return s;
  187.         proto_destroy (&s->rtp);
  188.     }
  189. error:
  190.     free (s);
  191.     return NULL;
  192. }
  193. /**
  194.  * Counter Mode encryption/decryption (ctr length = 16 bytes)
  195.  * with non-padded (truncated) text
  196.  */
  197. static int
  198. ctr_crypt (gcry_cipher_hd_t hd, const void *ctr, uint8_t *data, size_t len)
  199. {
  200.     const size_t ctrlen = 16;
  201.     div_t d = div (len, ctrlen);
  202.     if (gcry_cipher_setctr (hd, ctr, ctrlen)
  203.      || gcry_cipher_encrypt (hd, data, d.quot * ctrlen, NULL, 0))
  204.         return -1;
  205.     if (d.rem)
  206.     {
  207.         /* Truncated last block */
  208.         uint8_t dummy[ctrlen];
  209.         data += d.quot * ctrlen;
  210.         memcpy (dummy, data, d.rem);
  211.         memset (dummy + d.rem, 0, ctrlen - d.rem);
  212.         if (gcry_cipher_encrypt (hd, dummy, ctrlen, data, ctrlen))
  213.             return -1;
  214.         memcpy (data, dummy, d.rem);
  215.     }
  216.     return 0;
  217. }
  218. /**
  219.  * AES-CM key derivation (saltlen = 14 bytes)
  220.  */
  221. static int
  222. derive (gcry_cipher_hd_t prf, const void *salt,
  223.         const uint8_t *r, size_t rlen, uint8_t label,
  224.         void *out, size_t outlen)
  225. {
  226.     uint8_t iv[16];
  227.     memcpy (iv, salt, 14);
  228.     iv[14] = iv[15] = 0;
  229.     assert (rlen < 14);
  230.     iv[13 - rlen] ^= label;
  231.     for (size_t i = 0; i < rlen; i++)
  232.         iv[sizeof (iv) - rlen + i] ^= r[i];
  233.     memset (out, 0, outlen);
  234.     return ctr_crypt (prf, iv, out, outlen);
  235. }
  236. static int
  237. proto_derive (srtp_proto_t *p, gcry_cipher_hd_t prf,
  238.               const void *salt, size_t saltlen,
  239.               const uint8_t *r, size_t rlen, bool rtcp)
  240. {
  241.     if (saltlen != 14)
  242.         return -1;
  243.     uint8_t keybuf[20];
  244.     uint8_t label = rtcp ? SRTCP_CRYPT : SRTP_CRYPT;
  245.     if (derive (prf, salt, r, rlen, label++, keybuf, 16)
  246.      || gcry_cipher_setkey (p->cipher, keybuf, 16)
  247.      || derive (prf, salt, r, rlen, label++, keybuf, 20)
  248.      || gcry_md_setkey (p->mac, keybuf, 20)
  249.      || derive (prf, salt, r, rlen, label, p->salt, 14))
  250.         return -1;
  251.     return 0;
  252. }
  253. /**
  254.  * SRTP/SRTCP cipher/salt/MAC keys derivation.
  255.  */
  256. static int
  257. srtp_derive (srtp_session_t *s, const void *key, size_t keylen,
  258.              const void *salt, size_t saltlen)
  259. {
  260.     gcry_cipher_hd_t prf;
  261.     uint8_t r[6];
  262.     if (gcry_cipher_open (&prf, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, 0)
  263.      || gcry_cipher_setkey (prf, key, keylen))
  264.         return -1;
  265. #if 0
  266.     /* RTP key derivation */
  267.     if (s->kdr != 0)
  268.     {
  269.         uint64_t index = (((uint64_t)s->rtp_roc) << 16) | s->rtp_seq;
  270.         index /= s->kdr;
  271.         for (int i = sizeof (r) - 1; i >= 0; i--)
  272.         {
  273.             r[i] = index & 0xff;
  274.             index = index >> 8;
  275.         }
  276.     }
  277.     else
  278. #endif
  279.         memset (r, 0, sizeof (r));
  280.     if (proto_derive (&s->rtp, prf, salt, saltlen, r, 6, false))
  281.         return -1;
  282.     /* RTCP key derivation */
  283.     memcpy (r, &(uint32_t){ htonl (s->rtcp_index) }, 4);
  284.     if (proto_derive (&s->rtcp, prf, salt, saltlen, r, 4, true))
  285.         return -1;
  286.     (void)gcry_cipher_close (prf);
  287.     return 0;
  288. }
  289. /**
  290.  * Sets (or resets) the master key and master salt for a SRTP session.
  291.  * This must be done at least once before using rtp_send(), rtp_recv(),
  292.  * rtcp_send() or rtcp_recv(). Also, rekeying is required every
  293.  * 2^48 RTP packets or 2^31 RTCP packets (whichever comes first),
  294.  * otherwise the protocol security might be broken.
  295.  *
  296.  * @return 0 on success, in case of error:
  297.  *  EINVAL  invalid or unsupported key/salt sizes combination
  298.  */
  299. int
  300. srtp_setkey (srtp_session_t *s, const void *key, size_t keylen,
  301.              const void *salt, size_t saltlen)
  302. {
  303.     return srtp_derive (s, key, keylen, salt, saltlen) ? EINVAL : 0;
  304. }
  305. static int hexdigit (char c)
  306. {
  307.     if ((c >= '0') && (c <= '9'))
  308.         return c - '0';
  309.     if ((c >= 'A') && (c <= 'F'))
  310.         return c - 'A' + 0xA;
  311.     if ((c >= 'a') && (c <= 'f'))
  312.         return c - 'a' + 0xa;
  313.     return -1;
  314. }
  315. static ssize_t hexstring (const char *in, uint8_t *out, size_t outlen)
  316. {
  317.     size_t inlen = strlen (in);
  318.     if ((inlen > (2 * outlen)) || (inlen & 1))
  319.         return -1;
  320.     for (size_t i = 0; i < inlen; i += 2)
  321.     {
  322.         int a = hexdigit (in[i]), b = hexdigit (in[i + 1]);
  323.         if ((a == -1) || (b == -1))
  324.             return -1;
  325.         out[i / 2] = (a << 4) | b;
  326.     }
  327.     return inlen / 2;
  328. }
  329. /**
  330.  * Sets (or resets) the master key and master salt for a SRTP session
  331.  * from hexadecimal strings. See also srtp_setkey().
  332.  *
  333.  * @return 0 on success, in case of error:
  334.  *  EINVAL  invalid or unsupported key/salt sizes combination
  335.  */
  336. int
  337. srtp_setkeystring (srtp_session_t *s, const char *key, const char *salt)
  338. {
  339.     uint8_t bkey[16]; /* TODO/NOTE: hard-coded for AES */
  340.     uint8_t bsalt[14]; /* TODO/NOTE: hard-coded for the PRF-AES-CM */
  341.     ssize_t bkeylen = hexstring (key, bkey, sizeof (bkey));
  342.     ssize_t bsaltlen = hexstring (salt, bsalt, sizeof (bsalt));
  343.     if ((bkeylen == -1) || (bsaltlen == -1))
  344.         return EINVAL;
  345.     return srtp_setkey (s, bkey, bkeylen, bsalt, bsaltlen) ? EINVAL : 0;
  346. }
  347. /**
  348.  * Sets Roll-over-Counter Carry (RCC) rate for the SRTP session. If not
  349.  * specified (through this function), the default rate of ONE is assumed
  350.  * (i.e. every RTP packets will carry the RoC). RCC rate is ignored if none
  351.  * of the RCC mode has been selected.
  352.  *
  353.  * The RCC mode is selected through one of these flags for srtp_create():
  354.  *  SRTP_RCC_MODE1: integrity protection only for RoC carrying packets
  355.  *  SRTP_RCC_MODE2: integrity protection for all packets
  356.  *  SRTP_RCC_MODE3: no integrity protection
  357.  *
  358.  * RCC mode 3 is insecure. Compared to plain RTP, it provides confidentiality
  359.  * (through encryption) but is much more prone to DoS. It can only be used if
  360.  * anti-spoofing protection is provided by lower network layers (e.g. IPsec,
  361.  * or trusted routers and proper source address filtering).
  362.  *
  363.  * If RCC rate is 1, RCC mode 1 and 2 are functionally identical.
  364.  *
  365.  * @param rate RoC Carry rate (MUST NOT be zero)
  366.  */
  367. void srtp_setrcc_rate (srtp_session_t *s, uint16_t rate)
  368. {
  369.     assert (rate != 0);
  370.     s->rtp_rcc = rate;
  371. }
  372. /** AES-CM for RTP (salt = 14 bytes + 2 nul bytes) */
  373. static int
  374. rtp_crypt (gcry_cipher_hd_t hd, uint32_t ssrc, uint32_t roc, uint16_t seq,
  375.            const uint32_t *salt, uint8_t *data, size_t len)
  376. {
  377.     /* Determines cryptographic counter (IV) */
  378.     uint32_t counter[4];
  379.     counter[0] = salt[0];
  380.     counter[1] = salt[1] ^ ssrc;
  381.     counter[2] = salt[2] ^ htonl (roc);
  382.     counter[3] = salt[3] ^ htonl (seq << 16);
  383.     /* Encryption */
  384.     return ctr_crypt (hd, counter, data, len);
  385. }
  386. /** Determines SRTP Roll-Over-Counter (in host-byte order) */
  387. static uint32_t
  388. srtp_compute_roc (const srtp_session_t *s, uint16_t seq)
  389. {
  390.     uint32_t roc = s->rtp_roc;
  391.     if (((seq - s->rtp_seq) & 0xffff) < 0x8000)
  392.     {
  393.         /* Sequence is ahead, good */
  394.         if (seq < s->rtp_seq)
  395.             roc++; /* Sequence number wrap */
  396.     }
  397.     else
  398.     {
  399.         /* Sequence is late, bad */
  400.         if (seq > s->rtp_seq)
  401.             roc--; /* Wrap back */
  402.     }
  403.     return roc;
  404. }
  405. /** Returns RTP sequence (in host-byte order) */
  406. static inline uint16_t rtp_seq (const uint8_t *buf)
  407. {
  408.     return (buf[2] << 8) | buf[3];
  409. }
  410. /** Message Authentication and Integrity for RTP */
  411. static const uint8_t *
  412. rtp_digest (srtp_session_t *s, const uint8_t *data, size_t len,
  413.             uint32_t roc)
  414. {
  415.     const gcry_md_hd_t md = s->rtp.mac;
  416.     gcry_md_reset (md);
  417.     gcry_md_write (md, data, len);
  418.     gcry_md_write (md, &(uint32_t){ htonl (roc) }, 4);
  419.     return gcry_md_read (md, 0);
  420. }
  421. /**
  422.  * Encrypts/decrypts a RTP packet and updates SRTP context
  423.  * (CTR block cypher mode of operation has identical encryption and
  424.  * decryption function).
  425.  *
  426.  * @param buf RTP packet to be en-/decrypted
  427.  * @param len RTP packet length
  428.  *
  429.  * @return 0 on success, in case of error:
  430.  *  EINVAL  malformatted RTP packet
  431.  *  EACCES  replayed packet or out-of-window or sync lost
  432.  */
  433. static int srtp_crypt (srtp_session_t *s, uint8_t *buf, size_t len)
  434. {
  435.     assert (s != NULL);
  436.     if ((len < 12) || ((buf[0] >> 6) != 2))
  437.         return EINVAL;
  438.     /* Computes encryption offset */
  439.     uint16_t offset = 12;
  440.     offset += (buf[0] & 0xf) * 4; // skips CSRC
  441.     if (buf[0] & 0x10)
  442.     {
  443.         uint16_t extlen;
  444.         offset += 4;
  445.         if (len < offset)
  446.             return EINVAL;
  447.         memcpy (&extlen, buf + offset - 2, 2);
  448.         offset += htons (extlen); // skips RTP extension header
  449.     }
  450.     if (len < offset)
  451.         return EINVAL;
  452.     /* Determines RTP 48-bits counter and SSRC */
  453.     uint16_t seq = rtp_seq (buf);
  454.     uint32_t roc = srtp_compute_roc (s, seq), ssrc;
  455.     memcpy (&ssrc, buf + 8, 4);
  456.     /* Updates ROC and sequence (it's safe now) */
  457.     int16_t diff = seq - s->rtp_seq;
  458.     if (diff > 0)
  459.     {
  460.         /* Sequence in the future, good */
  461.         s->rtp.window = s->rtp.window << diff;
  462.         s->rtp.window |= 1;
  463.         s->rtp_seq = seq, s->rtp_roc = roc;
  464.     }
  465.     else
  466.     {
  467.         /* Sequence in the past/present, bad */
  468.         diff = -diff;
  469.         if ((diff >= 64) || ((s->rtp.window >> diff) & 1))
  470.             return EACCES; /* Replay attack */
  471.         s->rtp.window |= 1 << diff;
  472.     }
  473.     /* Encrypt/Decrypt */
  474.     if (s->flags & SRTP_UNENCRYPTED)
  475.         return 0;
  476.     if (rtp_crypt (s->rtp.cipher, ssrc, roc, seq, s->rtp.salt,
  477.                    buf + offset, len - offset))
  478.         return EINVAL;
  479.     return 0;
  480. }
  481. /**
  482.  * Turns a RTP packet into a SRTP packet: encrypt it, then computes
  483.  * the authentication tag and appends it.
  484.  * Note that you can encrypt packet in disorder.
  485.  *
  486.  * @param buf RTP packet to be encrypted/digested
  487.  * @param lenp pointer to the RTP packet length on entry,
  488.  *             set to the SRTP length on exit (undefined on non-ENOSPC error)
  489.  * @param bufsize size (bytes) of the packet buffer
  490.  *
  491.  * @return 0 on success, in case of error:
  492.  *  EINVAL  malformatted RTP packet or internal error
  493.  *  ENOSPC  bufsize is too small to add authentication tag
  494.  *          (<lenp> will hold the required byte size)
  495.  *  EACCES  packet would trigger a replay error on receiver
  496.  */
  497. int
  498. srtp_send (srtp_session_t *s, uint8_t *buf, size_t *lenp, size_t bufsize)
  499. {
  500.     size_t len = *lenp;
  501.     size_t tag_len = s->tag_len;
  502.     if (!(s->flags & SRTP_UNAUTHENTICATED))
  503.     {
  504.         *lenp = len + tag_len;
  505.         if (bufsize < (len + tag_len))
  506.             return ENOSPC;
  507.     }
  508.     int val = srtp_crypt (s, buf, len);
  509.     if (val)
  510.         return val;
  511.     if (!(s->flags & SRTP_UNAUTHENTICATED))
  512.     {
  513.         uint32_t roc = srtp_compute_roc (s, rtp_seq (buf));
  514.         const uint8_t *tag = rtp_digest (s, buf, len, roc);
  515.         if (rcc_mode (s))
  516.         {
  517.             assert (s->rtp_rcc);
  518.             if ((rtp_seq (buf) % s->rtp_rcc) == 0)
  519.             {
  520.                 memcpy (buf + len, &(uint32_t){ htonl (s->rtp_roc) }, 4);
  521.                 len += 4;
  522.                 if (rcc_mode (s) == 3)
  523.                     tag_len = 0;
  524.                 else
  525.                     tag_len -= 4;
  526.             }
  527.             else
  528.             {
  529.                 if (rcc_mode (s) & 1)
  530.                     tag_len = 0;
  531.             }
  532.         }
  533.         memcpy (buf + len, tag, tag_len);
  534.     }
  535.     return 0;
  536. }
  537. /**
  538.  * Turns a SRTP packet into a RTP packet: authenticates the packet,
  539.  * then decrypts it.
  540.  *
  541.  * @param buf RTP packet to be digested/decrypted
  542.  * @param lenp pointer to the SRTP packet length on entry,
  543.  *             set to the RTP length on exit (undefined in case of error)
  544.  *
  545.  * @return 0 on success, in case of error:
  546.  *  EINVAL  malformatted SRTP packet
  547.  *  EACCES  authentication failed (spoofed packet or out-of-sync)
  548.  */
  549. int
  550. srtp_recv (srtp_session_t *s, uint8_t *buf, size_t *lenp)
  551. {
  552.     size_t len = *lenp;
  553.     if (len < 12u)
  554.         return EINVAL;
  555.     if (!(s->flags & SRTP_UNAUTHENTICATED))
  556.     {
  557.         size_t tag_len = s->tag_len, roc_len = 0;
  558.         if (rcc_mode (s))
  559.         {
  560.             if ((rtp_seq (buf) % s->rtp_rcc) == 0)
  561.             {
  562.                 roc_len = 4;
  563.                 if (rcc_mode (s) == 3)
  564.                     tag_len = 0;
  565.                 else
  566.                     tag_len -= 4;
  567.             }
  568.             else
  569.             {
  570.                 if (rcc_mode (s) & 1)
  571.                     tag_len = 0; // RCC mode 1 or 3: no auth
  572.             }
  573.         }
  574.         if (len < (12u + roc_len + tag_len))
  575.             return EINVAL;
  576.         len -= roc_len + tag_len;
  577.         uint32_t roc = srtp_compute_roc (s, rtp_seq (buf)), rcc;
  578.         if (roc_len)
  579.         {
  580.             assert (roc_len == 4);
  581.             memcpy (&rcc, buf + len, 4);
  582.             rcc = ntohl (rcc);
  583.         }
  584.         else
  585.             rcc = roc;
  586.         const uint8_t *tag = rtp_digest (s, buf, len, rcc);
  587. #if 0
  588.         printf ("Computed: 0x");
  589.         for (unsigned i = 0; i < tag_len; i++)
  590.             printf ("%02x", tag[i]);
  591.         printf ("nReceived: 0x");
  592.         for (unsigned i = 0; i < tag_len; i++)
  593.             printf ("%02x", buf[len + roc_len + i]);
  594.         puts ("");
  595. #endif
  596.         if (memcmp (buf + len + roc_len, tag, tag_len))
  597.             return EACCES;
  598.         if (roc_len)
  599.         {
  600.             /* Authenticated packet carried a Roll-Over-Counter */
  601.             s->rtp_roc += rcc - roc;
  602.             assert (srtp_compute_roc (s, rtp_seq (buf)) == rcc);
  603.         }
  604.         *lenp = len;
  605.     }
  606.     return srtp_crypt (s, buf, len);
  607. }
  608. /** AES-CM for RTCP (salt = 14 bytes + 2 nul bytes) */
  609. static int
  610. rtcp_crypt (gcry_cipher_hd_t hd, uint32_t ssrc, uint32_t index,
  611.             const uint32_t *salt, uint8_t *data, size_t len)
  612. {
  613.     return rtp_crypt (hd, ssrc, index >> 16, index & 0xffff, salt, data, len);
  614. }
  615. /** Message Authentication and Integrity for RTCP */
  616. static const uint8_t *
  617. rtcp_digest (gcry_md_hd_t md, const void *data, size_t len)
  618. {
  619.     gcry_md_reset (md);
  620.     gcry_md_write (md, data, len);
  621.     return gcry_md_read (md, 0);
  622. }
  623. /**
  624.  * Encrypts/decrypts a RTCP packet and updates SRTCP context
  625.  * (CTR block cypher mode of operation has identical encryption and
  626.  * decryption function).
  627.  *
  628.  * @param buf RTCP packet to be en-/decrypted
  629.  * @param len RTCP packet length
  630.  *
  631.  * @return 0 on success, in case of error:
  632.  *  EINVAL  malformatted RTCP packet
  633.  */
  634. static int srtcp_crypt (srtp_session_t *s, uint8_t *buf, size_t len)
  635. {
  636.     assert (s != NULL);
  637.     /* 8-bytes unencrypted header, and 4-bytes unencrypted footer */
  638.     if ((len < 12) || ((buf[0] >> 6) != 2))
  639.         return EINVAL;
  640.     uint32_t index;
  641.     memcpy (&index, buf + len, 4);
  642.     index = ntohl (index);
  643.     if (((index >> 31) != 0) != ((s->flags & SRTCP_UNENCRYPTED) == 0))
  644.         return EINVAL; // E-bit mismatch
  645.     index &= ~(1 << 31); // clear E-bit for counter
  646.     /* Updates SRTCP index (safe here) */
  647.     int32_t diff = index - s->rtcp_index;
  648.     if (diff > 0)
  649.     {
  650.         /* Packet in the future, good */
  651.         s->rtcp.window = s->rtcp.window << diff;
  652.         s->rtcp.window |= 1;
  653.         s->rtcp_index = index;
  654.     }
  655.     else
  656.     {
  657.         /* Packet in the past/present, bad */
  658.         diff = -diff;
  659.         if ((diff >= 64) || ((s->rtcp.window >> diff) & 1))
  660.             return EACCES; // replay attack!
  661.         s->rtp.window |= 1 << diff;
  662.     }
  663.     /* Crypts SRTCP */
  664.     if (s->flags & SRTCP_UNENCRYPTED)
  665.         return 0;
  666.     uint32_t ssrc;
  667.     memcpy (&ssrc, buf + 4, 4);
  668.     if (rtcp_crypt (s->rtcp.cipher, ssrc, index, s->rtp.salt,
  669.                     buf + 8, len - 8))
  670.         return EINVAL;
  671.     return 0;
  672. }
  673. /**
  674.  * Turns a RTCP packet into a SRTCP packet: encrypt it, then computes
  675.  * the authentication tag and appends it.
  676.  *
  677.  * @param buf RTCP packet to be encrypted/digested
  678.  * @param lenp pointer to the RTCP packet length on entry,
  679.  *             set to the SRTCP length on exit (undefined in case of error)
  680.  * @param bufsize size (bytes) of the packet buffer
  681.  *
  682.  * @return 0 on success, in case of error:
  683.  *  EINVAL  malformatted RTCP packet or internal error
  684.  *  ENOSPC  bufsize is too small (to add index and authentication tag)
  685.  */
  686. int
  687. srtcp_send (srtp_session_t *s, uint8_t *buf, size_t *lenp, size_t bufsize)
  688. {
  689.     size_t len = *lenp;
  690.     if (bufsize < (len + 4 + s->tag_len))
  691.         return ENOSPC;
  692.     uint32_t index = ++s->rtcp_index;
  693.     if (index >> 31)
  694.         s->rtcp_index = index = 0; /* 31-bit wrap */
  695.     if ((s->flags & SRTCP_UNENCRYPTED) == 0)
  696.         index |= 0x80000000; /* Set Encrypted bit */
  697.     memcpy (buf + len, &(uint32_t){ htonl (index) }, 4);
  698.     int val = srtcp_crypt (s, buf, len);
  699.     if (val)
  700.         return val;
  701.     len += 4; /* Digests SRTCP index too */
  702.     const uint8_t *tag = rtcp_digest (s->rtp.mac, buf, len);
  703.     memcpy (buf + len, tag, s->tag_len);
  704.     *lenp = len + s->tag_len;
  705.     return 0;
  706. }
  707. /**
  708.  * Turns a SRTCP packet into a RTCP packet: authenticates the packet,
  709.  * then decrypts it.
  710.  *
  711.  * @param buf RTCP packet to be digested/decrypted
  712.  * @param lenp pointer to the SRTCP packet length on entry,
  713.  *             set to the RTCP length on exit (undefined in case of error)
  714.  *
  715.  * @return 0 on success, in case of error:
  716.  *  EINVAL  malformatted SRTCP packet
  717.  *  EACCES  authentication failed (spoofed packet or out-of-sync)
  718.  */
  719. int
  720. srtcp_recv (srtp_session_t *s, uint8_t *buf, size_t *lenp)
  721. {
  722.     size_t len = *lenp;
  723.     if (len < (4u + s->tag_len))
  724.         return EINVAL;
  725.     len -= s->tag_len;
  726.     const uint8_t *tag = rtcp_digest (s->rtp.mac, buf, len);
  727.     if (memcmp (buf + len, tag, s->tag_len))
  728.          return EACCES;
  729.     len -= 4; /* Remove SRTCP index before decryption */
  730.     *lenp = len;
  731.     return srtp_crypt (s, buf, len);
  732. }