Changeset 67da4884c3b2934ce028b9c437f23b3a5cfc9990
- Timestamp:
- 03/10/07 22:01:13
(1 year ago)
- Author:
- Rémi Denis-Courmont <rem@videolan.org>
- git-committer:
- Rémi Denis-Courmont <rem@videolan.org> 1173560473 +0000
- git-parent:
[0eeb4286f4b713f9c443f493185535afe34866aa]
- git-author:
- Rémi Denis-Courmont <rem@videolan.org> 1173560473 +0000
- Message:
SRTP/SRTCP receive window for replay attack protection
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r9775069 |
r67da488 |
|
| 73 | 73 | { |
|---|
| 74 | 74 | len = read (fd, buf, sizeof (buf)); |
|---|
| 75 | | if (srtp_recv (s, buf, &len)) |
|---|
| 76 | | fputs ("Cannot decrypt!\n", stderr); |
|---|
| | 75 | int val = srtp_recv (s, buf, &len); |
|---|
| | 76 | if (val) |
|---|
| | 77 | { |
|---|
| | 78 | fprintf (stderr, "Cannot decrypt: %s\n", strerror (val)); |
|---|
| | 79 | continue; |
|---|
| | 80 | } |
|---|
| | 81 | |
|---|
| 77 | 82 | puts ((char *)buf + 12); |
|---|
| 78 | | if (srtp_send (s, buf, &len, sizeof (buf)) || srtp_recv (s, buf, &len)) |
|---|
| 79 | | break; |
|---|
| | 83 | //if (srtp_send (s, buf, &len, sizeof (buf)) || srtp_recv (s, buf, &len)) |
|---|
| | 84 | // break; |
|---|
| 80 | 85 | puts ((char *)buf + 12); |
|---|
| 81 | 86 | } |
|---|
| r0eeb428 |
r67da488 |
|
| 39 | 39 | * Useful stuff: |
|---|
| 40 | 40 | * - ROC profile thingy (multicast really needs this) |
|---|
| 41 | | * - replay protection |
|---|
| 42 | 41 | * |
|---|
| 43 | 42 | * Useless stuff (because nothing depends on it): |
|---|
| … | … | |
| 441 | 440 | * @return 0 on success, in case of error: |
|---|
| 442 | 441 | * EINVAL malformatted RTP packet |
|---|
| | 442 | * EACCES replayed packet or out-of-window or sync lost |
|---|
| 443 | 443 | */ |
|---|
| 444 | 444 | static int srtp_crypt (srtp_session_t *s, uint8_t *buf, size_t len) |
|---|
| … | … | |
| 474 | 474 | |
|---|
| 475 | 475 | /* Updates ROC and sequence (it's safe now) */ |
|---|
| 476 | | if (roc > s->rtp_roc) |
|---|
| | 476 | int16_t diff = seq - s->rtp_seq; |
|---|
| | 477 | if (diff > 0) |
|---|
| | 478 | { |
|---|
| | 479 | /* Sequence in the future, good */ |
|---|
| | 480 | s->rtp.window = s->rtp.window << diff; |
|---|
| | 481 | s->rtp.window |= 1; |
|---|
| 477 | 482 | s->rtp_seq = seq, s->rtp_roc = roc; |
|---|
| | 483 | } |
|---|
| 478 | 484 | else |
|---|
| 479 | | if (seq > s->rtp_seq) |
|---|
| 480 | | s->rtp_seq = seq; |
|---|
| | 485 | { |
|---|
| | 486 | /* Sequence in the past/present, bad */ |
|---|
| | 487 | diff = -diff; |
|---|
| | 488 | if ((diff >= 64) || ((s->rtp.window >> diff) & 1)) |
|---|
| | 489 | return EACCES; /* Replay attack */ |
|---|
| | 490 | s->rtp.window |= 1 << diff; |
|---|
| | 491 | } |
|---|
| 481 | 492 | |
|---|
| 482 | 493 | /* Encrypt/Decrypt */ |
|---|
| … | … | |
| 505 | 516 | * EINVAL malformatted RTP packet or internal error |
|---|
| 506 | 517 | * ENOSPC bufsize is too small (to add authentication tag) |
|---|
| | 518 | * EACCES packet would trigger a replay error on receiver |
|---|
| 507 | 519 | */ |
|---|
| 508 | 520 | int |
|---|
| … | … | |
| 544 | 556 | { |
|---|
| 545 | 557 | size_t len = *lenp; |
|---|
| 546 | | /* FIXME: anti-replay */ |
|---|
| 547 | 558 | |
|---|
| 548 | 559 | if (!(s->flags & SRTP_UNAUTHENTICATED)) |
|---|
| … | … | |
| 601 | 612 | return EINVAL; |
|---|
| 602 | 613 | |
|---|
| 603 | | /* Updates SRTCP index (safe here) */ |
|---|
| 604 | 614 | uint32_t index; |
|---|
| 605 | 615 | memcpy (&index, buf + len, 4); |
|---|
| 606 | 616 | index = ntohl (index); |
|---|
| 607 | | if (((index - s->rtcp_index) & 0x7fffffff) < 0x40000000) |
|---|
| 608 | | s->rtcp_index = index; /* Update index */ |
|---|
| | 617 | if (((index >> 31) != 0) != ((s->flags & SRTCP_UNENCRYPTED) == 0)) |
|---|
| | 618 | return EINVAL; // E-bit mismatch |
|---|
| | 619 | |
|---|
| | 620 | index &= ~(1 << 31); // clear E-bit for counter |
|---|
| | 621 | |
|---|
| | 622 | /* Updates SRTCP index (safe here) */ |
|---|
| | 623 | int32_t diff = index - s->rtcp_index; |
|---|
| | 624 | if (diff > 0) |
|---|
| | 625 | { |
|---|
| | 626 | /* Packet in the future, good */ |
|---|
| | 627 | s->rtcp.window = s->rtcp.window << diff; |
|---|
| | 628 | s->rtcp.window |= 1; |
|---|
| | 629 | s->rtcp_index = index; |
|---|
| | 630 | } |
|---|
| | 631 | else |
|---|
| | 632 | { |
|---|
| | 633 | /* Packet in the past/present, bad */ |
|---|
| | 634 | diff = -diff; |
|---|
| | 635 | if ((diff >= 64) || ((s->rtcp.window >> diff) & 1)) |
|---|
| | 636 | return EACCES; // replay attack! |
|---|
| | 637 | s->rtp.window |= 1 << diff; |
|---|
| | 638 | } |
|---|
| 609 | 639 | |
|---|
| 610 | 640 | /* Crypts SRTCP */ |
|---|
| … | … | |
| 679 | 709 | { |
|---|
| 680 | 710 | size_t len = *lenp; |
|---|
| 681 | | /* FIXME: anti-replay ?? */ |
|---|
| 682 | 711 | |
|---|
| 683 | 712 | if (len < (4u + s->tag_len)) |
|---|