Changeset 54a4638723464f86744b43be273474367a131891
- Timestamp:
- 03/10/07 21:00:10
(1 year ago)
- Author:
- Rémi Denis-Courmont <rem@videolan.org>
- git-committer:
- Rémi Denis-Courmont <rem@videolan.org> 1173556810 +0000
- git-parent:
[a7c26dab2123bdc2fbb285d7aaeed6d66976b4d4]
- git-author:
- Rémi Denis-Courmont <rem@videolan.org> 1173556810 +0000
- Message:
Fix SRTP Roll-Over-Counter handling
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r9775069 |
r54a4638 |
|
| 388 | 388 | |
|---|
| 389 | 389 | |
|---|
| | 390 | /** Determines SRTP Roll-Over-Counter (in host-byte order) */ |
|---|
| | 391 | static uint32_t |
|---|
| | 392 | srtp_compute_roc (const srtp_session_t *s, uint16_t seq) |
|---|
| | 393 | { |
|---|
| | 394 | uint32_t roc = s->rtp_roc; |
|---|
| | 395 | |
|---|
| | 396 | if (((seq - s->rtp_seq) & 0xffff) < 0x8000) |
|---|
| | 397 | { |
|---|
| | 398 | /* Sequence is ahead, good */ |
|---|
| | 399 | if (seq < s->rtp_seq) |
|---|
| | 400 | roc++; /* Sequence number wrap */ |
|---|
| | 401 | } |
|---|
| | 402 | else |
|---|
| | 403 | { |
|---|
| | 404 | /* Sequence is late, bad */ |
|---|
| | 405 | if (seq > s->rtp_seq) |
|---|
| | 406 | roc--; /* Wrap back */ |
|---|
| | 407 | } |
|---|
| | 408 | return roc; |
|---|
| | 409 | } |
|---|
| | 410 | |
|---|
| | 411 | |
|---|
| | 412 | /** Returns RTP sequence (in host-byte order) */ |
|---|
| | 413 | static inline uint16_t rtp_seq (const uint8_t *buf) |
|---|
| | 414 | { |
|---|
| | 415 | return (buf[2] << 8) | buf[3]; |
|---|
| | 416 | } |
|---|
| | 417 | |
|---|
| | 418 | |
|---|
| 390 | 419 | /** Message Authentication and Integrity for RTP */ |
|---|
| 391 | 420 | static const uint8_t * |
|---|
| 392 | | rtp_digest (gcry_md_hd_t md, const void *data, size_t len, uint32_t roc) |
|---|
| 393 | | { |
|---|
| | 421 | rtp_digest (srtp_session_t *s, const uint8_t *data, size_t len) |
|---|
| | 422 | { |
|---|
| | 423 | const gcry_md_hd_t md = s->rtp.mac; |
|---|
| | 424 | uint32_t roc = htonl (srtp_compute_roc (s, rtp_seq (data))); |
|---|
| | 425 | |
|---|
| 394 | 426 | gcry_md_reset (md); |
|---|
| 395 | 427 | gcry_md_write (md, data, len); |
|---|
| 396 | | gcry_md_write (md, &(uint32_t){ htonl (roc) }, 4); |
|---|
| | 428 | gcry_md_write (md, &roc, 4); |
|---|
| 397 | 429 | return gcry_md_read (md, 0); |
|---|
| 398 | 430 | } |
|---|
| … | … | |
| 437 | 469 | |
|---|
| 438 | 470 | /* Determines RTP 48-bits counter and SSRC */ |
|---|
| 439 | | uint32_t ssrc; |
|---|
| | 471 | uint16_t seq = rtp_seq (buf); |
|---|
| | 472 | uint32_t roc = srtp_compute_roc (s, seq), ssrc; |
|---|
| 440 | 473 | memcpy (&ssrc, buf + 8, 4); |
|---|
| 441 | 474 | |
|---|
| 442 | | uint16_t seq = (buf[2] << 8) | buf[3]; |
|---|
| 443 | | if (((seq - s->rtp_seq) & 0xffff) < 32768) |
|---|
| 444 | | { |
|---|
| 445 | | if (seq < s->rtp_seq) |
|---|
| 446 | | s->rtp_roc++; /* Sequence number wrap */ |
|---|
| 447 | | } |
|---|
| | 475 | /* Updates ROC and sequence (it's safe now) */ |
|---|
| | 476 | if (roc > s->rtp_roc) |
|---|
| | 477 | s->rtp_seq = seq, s->rtp_roc = roc; |
|---|
| 448 | 478 | else |
|---|
| 449 | | { |
|---|
| 450 | | if (seq > s->rtp_seq) |
|---|
| 451 | | s->rtp_roc--; |
|---|
| 452 | | } |
|---|
| 453 | | |
|---|
| 454 | | s->rtp_seq = seq; |
|---|
| 455 | | |
|---|
| | 479 | if (seq > s->rtp_seq) |
|---|
| | 480 | s->rtp_seq = seq; |
|---|
| | 481 | |
|---|
| | 482 | /* Encrypt/Decrypt */ |
|---|
| 456 | 483 | if (s->flags & SRTP_UNENCRYPTED) |
|---|
| 457 | 484 | return 0; |
|---|
| 458 | 485 | |
|---|
| 459 | | if (rtp_crypt (s->rtp.cipher, ssrc, s->rtp_roc, seq, s->rtp.salt, |
|---|
| | 486 | if (rtp_crypt (s->rtp.cipher, ssrc, roc, seq, s->rtp.salt, |
|---|
| 460 | 487 | buf + offset, len - offset)) |
|---|
| 461 | 488 | return EINVAL; |
|---|
| … | … | |
| 487 | 514 | return val; |
|---|
| 488 | 515 | |
|---|
| 489 | | if (s->flags & SRTP_UNAUTHENTICATED) |
|---|
| 490 | | return 0; |
|---|
| 491 | | |
|---|
| 492 | | if (bufsize < (len + s->tag_len)) |
|---|
| 493 | | return ENOSPC; |
|---|
| 494 | | |
|---|
| 495 | | const uint8_t *tag = rtp_digest (s->rtp.mac, buf, len, s->rtp_roc); |
|---|
| 496 | | memcpy (buf + len, tag, s->tag_len); |
|---|
| 497 | | *lenp = len + s->tag_len; |
|---|
| | 516 | if (!(s->flags & SRTP_UNAUTHENTICATED)) |
|---|
| | 517 | { |
|---|
| | 518 | if (bufsize < (len + s->tag_len)) |
|---|
| | 519 | return ENOSPC; |
|---|
| | 520 | |
|---|
| | 521 | const uint8_t *tag = rtp_digest (s, buf, len); |
|---|
| | 522 | memcpy (buf + len, tag, s->tag_len); |
|---|
| | 523 | *lenp = len + s->tag_len; |
|---|
| | 524 | } |
|---|
| 498 | 525 | |
|---|
| 499 | 526 | return 0; |
|---|
| … | … | |
| 521 | 548 | if (!(s->flags & SRTP_UNAUTHENTICATED)) |
|---|
| 522 | 549 | { |
|---|
| 523 | | if (len < s->tag_len) |
|---|
| | 550 | if (len < (12u + s->tag_len)) |
|---|
| 524 | 551 | return EINVAL; |
|---|
| 525 | 552 | len -= s->tag_len; |
|---|
| 526 | 553 | |
|---|
| 527 | | const uint8_t *tag = rtp_digest (s->rtp.mac, buf, len, s->rtp_roc); |
|---|
| | 554 | const uint8_t *tag = rtp_digest (s, buf, len); |
|---|
| 528 | 555 | if (memcmp (buf + len, tag, s->tag_len)) |
|---|
| 529 | 556 | return EACCES; |
|---|