Changeset 54a4638723464f86744b43be273474367a131891

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

    r9775069 r54a4638  
    388388 
    389389 
     390/** Determines SRTP Roll-Over-Counter (in host-byte order) */ 
     391static uint32_t 
     392srtp_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) */ 
     413static inline uint16_t rtp_seq (const uint8_t *buf) 
     414{ 
     415    return (buf[2] << 8) | buf[3]; 
     416} 
     417 
     418 
    390419/** Message Authentication and Integrity for RTP */ 
    391420static const uint8_t * 
    392 rtp_digest (gcry_md_hd_t md, const void *data, size_t len, uint32_t roc) 
    393 
     421rtp_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 
    394426    gcry_md_reset (md); 
    395427    gcry_md_write (md, data, len); 
    396     gcry_md_write (md, &(uint32_t){ htonl (roc) }, 4); 
     428    gcry_md_write (md, &roc, 4); 
    397429    return gcry_md_read (md, 0); 
    398430} 
     
    437469 
    438470    /* 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; 
    440473    memcpy (&ssrc, buf + 8, 4); 
    441474 
    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; 
    448478    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 */ 
    456483    if (s->flags & SRTP_UNENCRYPTED) 
    457484        return 0; 
    458485 
    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, 
    460487                   buf + offset, len - offset)) 
    461488        return EINVAL; 
     
    487514        return val; 
    488515 
    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    } 
    498525 
    499526    return 0; 
     
    521548    if (!(s->flags & SRTP_UNAUTHENTICATED)) 
    522549    { 
    523         if (len < s->tag_len
     550        if (len < (12u + s->tag_len)
    524551            return EINVAL; 
    525552        len -= s->tag_len; 
    526553 
    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); 
    528555        if (memcmp (buf + len, tag, s->tag_len)) 
    529556            return EACCES;