Changeset e5c071abd8c79d19f3f6e19f626540e241c36849
- Timestamp:
- 03/10/07 19:06:47 (1 year ago)
- git-parent:
- Files:
-
- libs/srtp/srtp.c (modified) (13 diffs)
- libs/srtp/srtp.h (modified) (1 diff)
- libs/srtp/test-aes.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
libs/srtp/srtp.c
reb7428c re5c071a 38 38 /* TODO: 39 39 * Useful stuff: 40 * - ROC profil thingy (multicast really needs this)40 * - ROC profile thingy (multicast really needs this) 41 41 * - replay protection 42 *43 * Requirements for conformance:44 * - suites with NULL cipher45 * - SRTCP46 42 * 47 43 * Useless stuff (because nothing depends on it): … … 159 155 160 156 /** 161 * Allocates a Secure RTP session. 157 * Allocates a Secure RTP one-way session. 158 * The same session cannot be used both ways because this would confuse 159 * internal cryptographic counters; it is however of course feasible to open 160 * multiple simultaneous sessions with the same master key. 162 161 * 163 162 * @param name cipher-suite name … … 258 257 } 259 258 260 #include <stdio.h>261 259 262 260 static int … … 268 266 return -1; 269 267 270 uint 32_t cipherkey[4], authkey[5];268 uint8_t keybuf[20]; 271 269 uint8_t label = rtcp ? SRTCP_CRYPT : SRTP_CRYPT; 272 270 273 if (derive (prf, salt, r, rlen, label++, cipherkey, 16)274 || gcry_cipher_setkey (p->cipher, cipherkey, 16)275 || derive (prf, salt, r, rlen, label++, authkey, 20)276 || gcry_md_setkey (p->mac, authkey, 20)277 || derive (prf, salt, r, rlen, label ++, p->salt, 14))271 if (derive (prf, salt, r, rlen, label++, keybuf, 16) 272 || gcry_cipher_setkey (p->cipher, keybuf, 16) 273 || derive (prf, salt, r, rlen, label++, keybuf, 20) 274 || gcry_md_setkey (p->mac, keybuf, 20) 275 || derive (prf, salt, r, rlen, label, p->salt, 14)) 278 276 return -1; 279 280 debug (" cipher key: %08x%08x%08x%08x\n auth key: %08x%08x%08x%08x%08x\n",281 ntohl (cipherkey[0]), ntohl (cipherkey[1]), ntohl (cipherkey[2]),282 ntohl (cipherkey[3]), ntohl (authkey[0]), ntohl (authkey[1]),283 ntohl (authkey[2]), ntohl (authkey[3]), ntohl (authkey[4]));284 277 285 278 return 0; … … 330 323 331 324 332 333 325 /** 334 326 * Sets (or resets) the master key and master salt for a SRTP session. … … 351 343 /** AES-CM encryption/decryption (ctr length = 16 bytes) */ 352 344 static int 353 encrypt (gcry_cipher_hd_t hd, uint32_t *ctr, uint8_t *data, size_t len)345 ctr_crypt (gcry_cipher_hd_t hd, uint32_t *ctr, uint8_t *data, size_t len) 354 346 { 355 347 const size_t ctrlen = 16; … … 383 375 384 376 /** AES-CM for RTP (salt = 14 bytes + 2 nul bytes) */ 385 static in line int386 rtp_ encrypt (gcry_cipher_hd_t hd, uint32_t ssrc, uint32_t roc, uint16_t seq,387 const uint32_t *salt, uint8_t *data, size_t len)377 static int 378 rtp_crypt (gcry_cipher_hd_t hd, uint32_t ssrc, uint32_t roc, uint16_t seq, 379 const uint32_t *salt, uint8_t *data, size_t len) 388 380 { 389 381 /* Determines cryptographic counter (IV) */ … … 395 387 396 388 /* Encryption */ 397 return encrypt (hd, counter, data, len);389 return ctr_crypt (hd, counter, data, len); 398 390 } 399 391 … … 415 407 * decryption function). 416 408 * 417 * @param buf RTP packet to be en crypted/digested409 * @param buf RTP packet to be en-/decrypted 418 410 * @param len RTP packet length 419 411 * … … 468 460 return 0; 469 461 470 if (rtp_ encrypt (s->rtp.cipher, ssrc, s->rtp_roc, seq, s->rtp.salt,471 buf + offset, len - offset))462 if (rtp_crypt (s->rtp.cipher, ssrc, s->rtp_roc, seq, s->rtp.salt, 463 buf + offset, len - offset)) 472 464 return EINVAL; 473 465 … … 517 509 * 518 510 * @param buf RTP packet to be digested/decrypted 519 * @param lenp pointer to the RTP packet length on entry,520 * set to the SRTP length on exit (undefined in case of error)511 * @param lenp pointer to the SRTP packet length on entry, 512 * set to the RTP length on exit (undefined in case of error) 521 513 * 522 514 * @return 0 on success, in case of error: … … 528 520 { 529 521 size_t len = *lenp; 522 /* FIXME: anti-replay */ 530 523 531 524 if (!(s->flags & SRTP_UNAUTHENTICATED)) … … 534 527 return EINVAL; 535 528 len -= s->tag_len; 536 *lenp = len;537 529 538 530 const uint8_t *tag = rtp_digest (s->rtp.mac, buf, len, s->rtp_roc); 539 debug (" Auth tag: %08x%08x%04x (wanted)\n"540 " Auth tag: %08x%08x%04x (recv'd)\n",541 ntohl (((uint32_t *)tag)[0]), ntohl (((uint32_t *)tag)[1]),542 ntohs (((uint16_t *)tag)[4]),543 ntohl (((uint32_t *)w)[0]), ntohl (((uint32_t *)w)[1]),544 ntohs (((uint16_t *)w)[4]));545 531 if (memcmp (buf + len, tag, s->tag_len)) 546 532 return EACCES; 547 } 548 549 /* FIXME: anti-replay */533 534 *lenp = len; 535 } 550 536 551 537 return srtp_crypt (s, buf, len); 552 538 } 553 539 540 541 /** AES-CM for RTCP (salt = 14 bytes + 2 nul bytes) */ 542 static int 543 rtcp_crypt (gcry_cipher_hd_t hd, uint32_t ssrc, uint32_t index, 544 const uint32_t *salt, uint8_t *data, size_t len) 545 { 546 return rtp_crypt (hd, ssrc, index >> 16, index & 0xffff, salt, data, len); 547 } 548 549 550 /** Message Authentication and Integrity for RTCP */ 551 static const uint8_t * 552 rtcp_digest (gcry_md_hd_t md, const void *data, size_t len) 553 { 554 gcry_md_reset (md); 555 gcry_md_write (md, data, len); 556 return gcry_md_read (md, 0); 557 } 558 559 560 /** 561 * Encrypts/decrypts a RTCP packet and updates SRTCP context 562 * (CTR block cypher mode of operation has identical encryption and 563 * decryption function). 564 * 565 * @param buf RTCP packet to be en-/decrypted 566 * @param len RTCP packet length 567 * 568 * @return 0 on success, in case of error: 569 * EINVAL malformatted RTCP packet 570 */ 571 static int srtcp_crypt (srtp_session_t *s, uint8_t *buf, size_t len) 572 { 573 assert (s != NULL); 574 575 /* 8-bytes unencrypted header, and 4-bytes unencrypted footer */ 576 if ((len < 12) || ((buf[0] >> 6) != 2)) 577 return EINVAL; 578 579 uint32_t index = s->rtcp_index++; 580 if (index == 0x7fffffff) 581 s->rtcp_index = 0; /* 31-bit wrap */ 582 583 if (s->flags & SRTCP_UNENCRYPTED) 584 return 0; 585 586 uint32_t ssrc; 587 memcpy (&ssrc, buf + 4, 4); 588 589 if (rtcp_crypt (s->rtcp.cipher, ssrc, index, s->rtp.salt, 590 buf + 8, len - 8)) 591 return EINVAL; 592 return 0; 593 } 594 595 596 /** 597 * Turns a RTCP packet into a SRTCP packet: encrypt it, then computes 598 * the authentication tag and appends it. 599 * 600 * @param buf RTCP packet to be encrypted/digested 601 * @param lenp pointer to the RTCP packet length on entry, 602 * set to the SRTCP length on exit (undefined in case of error) 603 * @param bufsize size (bytes) of the packet buffer 604 * 605 * @return 0 on success, in case of error: 606 * EINVAL malformatted RTCP packet or internal error 607 * ENOSPC bufsize is too small (to add index and authentication tag) 608 */ 609 int 610 srtcp_send (srtp_session_t *s, uint8_t *buf, size_t *lenp, size_t bufsize) 611 { 612 size_t len = *lenp; 613 if (bufsize < (len + 4 + s->tag_len)) 614 return ENOSPC; 615 616 uint32_t index = s->rtcp_index; 617 if ((s->flags & SRTCP_UNENCRYPTED) == 0) 618 index |= 0x80000000; /* Set Encrypted bit */ 619 memcpy (buf + len, &(uint32_t){ htonl (index) }, 4); 620 621 int val = srtcp_crypt (s, buf, len); 622 if (val) 623 return val; 624 625 len += 4; /* Digest SRTCP index too */ 626 627 const uint8_t *tag = rtcp_digest (s->rtp.mac, buf, len); 628 memcpy (buf + len, tag, s->tag_len); 629 *lenp = len + s->tag_len; 630 return 0; 631 } 632 633 634 /** 635 * Turns a SRTCP packet into a RTCP packet: authenticates the packet, 636 * then decrypts it. 637 * 638 * @param buf RTCP packet to be digested/decrypted 639 * @param lenp pointer to the SRTCP packet length on entry, 640 * set to the RTCP length on exit (undefined in case of error) 641 * 642 * @return 0 on success, in case of error: 643 * EINVAL malformatted SRTCP packet 644 * EACCES authentication failed (spoofed packet or out-of-sync) 645 */ 646 int 647 srtcp_recv (srtp_session_t *s, uint8_t *buf, size_t *lenp) 648 { 649 size_t len = *lenp; 650 /* FIXME: anti-replay ?? */ 651 652 if (len < (4u + s->tag_len)) 653 return EINVAL; 654 len -= s->tag_len; 655 656 const uint8_t *tag = rtcp_digest (s->rtp.mac, buf, len); 657 if (memcmp (buf + len, tag, s->tag_len)) 658 return EACCES; 659 660 len -= 4; /* Remove SRTCP index befor decryption */ 661 *lenp = len; 662 663 return srtp_crypt (s, buf, len); 664 } 665 libs/srtp/srtp.h
r10ee356 re5c071a 40 40 uint16_t winsize); 41 41 void srtp_destroy (srtp_session_t *s); 42 int srtp_setkey (srtp_session_t *s, const void *key, size_t keylen, 43 const void *salt, size_t saltlen); 44 42 45 int srtp_send (srtp_session_t *s, uint8_t *buf, size_t *lenp, size_t maxsize); 43 46 int srtp_recv (srtp_session_t *s, uint8_t *buf, size_t *lenp); 47 int srtcp_send (srtp_session_t *s, uint8_t *buf, size_t *lenp, size_t maxsiz); 48 int srtcp_recv (srtp_session_t *s, uint8_t *buf, size_t *lenp); 44 49 45 int srtp_setkey (srtp_session_t *s, const void *key, size_t keylen,46 const void *salt, size_t saltlen);47 50 # ifdef __cplusplus 48 51 } libs/srtp/test-aes.c
r10ee356 re5c071a 118 118 fatal ("Cipher key error"); 119 119 120 if (rtp_ encrypt (hd, 0, 0, 0, salt, buf, 0xff020))120 if (rtp_crypt (hd, 0, 0, 0, salt, buf, 0xff020)) 121 121 fatal ("Encryption failure"); 122 122 gcry_cipher_close (hd);
