Changeset 67da4884c3b2934ce028b9c437f23b3a5cfc9990

Show
Ignore:
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
  • libs/srtp/recv.c

    r9775069 r67da488  
    7373    { 
    7474        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 
    7782        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; 
    8085        puts ((char *)buf + 12); 
    8186    } 
  • libs/srtp/srtp.c

    r0eeb428 r67da488  
    3939 * Useful stuff: 
    4040 * - ROC profile thingy (multicast really needs this) 
    41  * - replay protection 
    4241 * 
    4342 * Useless stuff (because nothing depends on it): 
     
    441440 * @return 0 on success, in case of error: 
    442441 *  EINVAL  malformatted RTP packet 
     442 *  EACCES  replayed packet or out-of-window or sync lost 
    443443 */ 
    444444static int srtp_crypt (srtp_session_t *s, uint8_t *buf, size_t len) 
     
    474474 
    475475    /* 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; 
    477482        s->rtp_seq = seq, s->rtp_roc = roc; 
     483    } 
    478484    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    } 
    481492 
    482493    /* Encrypt/Decrypt */ 
     
    505516 *  EINVAL  malformatted RTP packet or internal error 
    506517 *  ENOSPC  bufsize is too small (to add authentication tag) 
     518 *  EACCES  packet would trigger a replay error on receiver 
    507519 */ 
    508520int 
     
    544556{ 
    545557    size_t len = *lenp; 
    546     /* FIXME: anti-replay */ 
    547558 
    548559    if (!(s->flags & SRTP_UNAUTHENTICATED)) 
     
    601612        return EINVAL; 
    602613 
    603     /* Updates SRTCP index (safe here) */ 
    604614    uint32_t index; 
    605615    memcpy (&index, buf + len, 4); 
    606616    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    } 
    609639 
    610640    /* Crypts SRTCP */ 
     
    679709{ 
    680710    size_t len = *lenp; 
    681     /* FIXME: anti-replay ?? */ 
    682711 
    683712    if (len < (4u + s->tag_len))