diff --git a/draft-ietf-codec-opus-update-04 b/draft-ietf-codec-opus-update-04 deleted file mode 100644 index e50216d..0000000 --- a/draft-ietf-codec-opus-update-04 +++ /dev/null @@ -1,753 +0,0 @@ - - - - - - - - - - - - - - - - - - draft-ietf-codec-opus-update-04 - Updates to the Opus Audio Codec - - - - - - - - -
-
-
- -
-[Docs] [txt|pdf] [Tracker] [WG] [Email] [Diff1] [Diff2] [Nits]
-
-Versions: (draft-valin-codec-opus-update) 00 - 01 02 03 04
-
-
-Network Working Group                                          JM. Valin
-Internet-Draft                                       Mozilla Corporation
-Intended status: Standards Track                                  K. Vos
-Expires: April 24, 2017                                          vocTone
-                                                        October 21, 2016
-
-
-                    Updates to the Opus Audio Codec
-                    draft-ietf-codec-opus-update-04
-
-Abstract
-
-   This document addresses minor issues that were found in the
-   specification of the Opus audio codec in RFC 6716 [RFC6716].
-
-Status of This Memo
-
-   This Internet-Draft is submitted in full conformance with the
-   provisions of BCP 78 and BCP 79.
-
-   Internet-Drafts are working documents of the Internet Engineering
-   Task Force (IETF).  Note that other groups may also distribute
-   working documents as Internet-Drafts.  The list of current Internet-
-   Drafts is at http://datatracker.ietf.org/drafts/current/.
-
-   Internet-Drafts are draft documents valid for a maximum of six months
-   and may be updated, replaced, or obsoleted by other documents at any
-   time.  It is inappropriate to use Internet-Drafts as reference
-   material or to cite them other than as "work in progress."
-
-   This Internet-Draft will expire on April 24, 2017.
-
-Copyright Notice
-
-   Copyright (c) 2016 IETF Trust and the persons identified as the
-   document authors.  All rights reserved.
-
-   This document is subject to BCP 78 and the IETF Trust's Legal
-   Provisions Relating to IETF Documents
-   (http://trustee.ietf.org/license-info) in effect on the date of
-   publication of this document.  Please review these documents
-   carefully, as they describe your rights and restrictions with respect
-   to this document.  Code Components extracted from this document must
-   include Simplified BSD License text as described in Section 4.e of
-   the Trust Legal Provisions and are provided without warranty as
-   described in the Simplified BSD License.
-
-
-
-
-
-Valin & Vos              Expires April 24, 2017                 [Page 1]
-

-Internet-Draft                 Opus Update                  October 2016
-
-
-Table of Contents
-
-   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
-   2.  Terminology . . . . . . . . . . . . . . . . . . . . . . . . .   2
-   3.  Stereo State Reset in SILK  . . . . . . . . . . . . . . . . .   2
-   4.  Parsing of the Opus Packet Padding  . . . . . . . . . . . . .   3
-   5.  Resampler buffer  . . . . . . . . . . . . . . . . . . . . . .   4
-   6.  Integer wrap-around in inverse gain computation . . . . . . .   5
-   7.  Integer wrap-around in LSF decoding . . . . . . . . . . . . .   6
-   8.  Cap on Band Energy  . . . . . . . . . . . . . . . . . . . . .   6
-   9.  Hybrid Folding  . . . . . . . . . . . . . . . . . . . . . . .   7
-   10. Downmix to Mono . . . . . . . . . . . . . . . . . . . . . . .   9
-   11. New Test Vectors  . . . . . . . . . . . . . . . . . . . . . .   9
-   12. IANA Considerations . . . . . . . . . . . . . . . . . . . . .   9
-   13. Acknowledgements  . . . . . . . . . . . . . . . . . . . . . .   9
-   14. References  . . . . . . . . . . . . . . . . . . . . . . . . .  10
-   Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  10
-
-1.  Introduction
-
-   This document addresses minor issues that were discovered in the
-   reference implementation of the Opus codec that serves as the
-   specification in RFC 6716 [RFC6716].  Only issues affecting the
-   decoder are listed here.  An up-to-date implementation of the Opus
-   encoder can be found at http://opus-codec.org/. The updated
-   specification remains fully compatible with the original
-   specification.
-
-2.  Terminology
-
-   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-   document are to be interpreted as described in RFC 2119 [RFC2119].
-
-3.  Stereo State Reset in SILK
-
-   The reference implementation does not reinitialize the stereo state
-   during a mode switch.  The old stereo memory can produce a brief
-   impulse (i.e. single sample) in the decoded audio.  This can be fixed
-   by changing silk/dec_API.c at line 72:
-
-
-
-
-
-
-
-
-
-
-
-Valin & Vos              Expires April 24, 2017                 [Page 2]
-

-Internet-Draft                 Opus Update                  October 2016
-
-
-        for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) {
-            ret  = silk_init_decoder( &channel_state[ n ] );
-        }
-   +    silk_memset(&((silk_decoder *)decState)->sStereo, 0,
-   +                sizeof(((silk_decoder *)decState)->sStereo));
-   +    /* Not strictly needed, but it's cleaner that way */
-   +    ((silk_decoder *)decState)->prev_decode_only_middle = 0;
-
-        return ret;
-    }
-
-   This change affects the normative part of the decoder, although the
-   amount of change is too small to make a significant impact on
-   testvectors.
-
-4.  Parsing of the Opus Packet Padding
-
-   It was discovered that some invalid packets of very large size could
-   trigger an out-of-bounds read in the Opus packet parsing code
-   responsible for padding.  This is due to an integer overflow if the
-   signaled padding exceeds 2^31-1 bytes (the actual packet may be
-   smaller).  The code can be fixed by applying the following changes at
-   line 596 of src/opus_decoder.c:
-
-          /* Padding flag is bit 6 */
-          if (ch&0x40)
-          {
-   -         int padding=0;
-             int p;
-             do {
-                if (len<=0)
-                   return OPUS_INVALID_PACKET;
-                p = *data++;
-                len--;
-   -            padding += p==255 ? 254: p;
-   +            len -= p==255 ? 254: p;
-             } while (p==255);
-   -         len -= padding;
-          }
-
-   This packet parsing issue is limited to reading memory up to about 60
-   kB beyond the compressed buffer.  This can only be triggered by a
-   compressed packet more than about 16 MB long, so it's not a problem
-   for RTP.  In theory, it _could_ crash a file decoder (e.g.  Opus in
-   Ogg) if the memory just after the incoming packet is out-of-range,
-   but our attempts to trigger such a crash in a production application
-   built using an affected version of the Opus decoder failed.
-
-
-
-
-Valin & Vos              Expires April 24, 2017                 [Page 3]
-

-Internet-Draft                 Opus Update                  October 2016
-
-
-5.  Resampler buffer
-
-   The SILK resampler had the following issues:
-
-   1.  The calls to memcpy() were using sizeof(opus_int32), but the type
-       of the local buffer was opus_int16.
-
-   2.  Because the size was wrong, this potentially allowed the source
-       and destination regions of the memcpy() to overlap.  We _believe_
-       that nSamplesIn is at least fs_in_khZ, which is at least 8.
-       Since RESAMPLER_ORDER_FIR_12 is only 8, that should not be a
-       problem once the type size is fixed.
-
-   3.  The size of the buffer used RESAMPLER_MAX_BATCH_SIZE_IN, but the
-       data stored in it was actually _twice_ the input batch size
-       (nSamplesIn<<1).
-
-   The fact that the code never produced any error in testing (including
-   when run under the Valgrind memory debugger), suggests that in
-   practice the batch sizes are reasonable enough that none of the
-   issues above was ever a problem.  However, proving that is non-
-   obvious.
-
-   The code can be fixed by applying the following changes to line 70 of
-   silk/resampler_private_IIR_FIR.c:
-
-    )
-    {
-        silk_resampler_state_struct *S = \
-   (silk_resampler_state_struct *)SS;
-        opus_int32 nSamplesIn;
-        opus_int32 max_index_Q16, index_increment_Q16;
-   -    opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + \
-   RESAMPLER_ORDER_FIR_12 ];
-   +    opus_int16 buf[ 2*RESAMPLER_MAX_BATCH_SIZE_IN + \
-   RESAMPLER_ORDER_FIR_12 ];
-
-        /* Copy buffered samples to start of buffer */
-   -    silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 \
-   * sizeof( opus_int32 ) );
-   +    silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 \
-   * sizeof( opus_int16 ) );
-
-        /* Iterate over blocks of frameSizeIn input samples */
-        index_increment_Q16 = S->invRatio_Q16;
-        while( 1 ) {
-            nSamplesIn = silk_min( inLen, S->batchSize );
-
-
-
-
-Valin & Vos              Expires April 24, 2017                 [Page 4]
-

-Internet-Draft                 Opus Update                  October 2016
-
-
-            /* Upsample 2x */
-            silk_resampler_private_up2_HQ( S->sIIR, &buf[ \
-   RESAMPLER_ORDER_FIR_12 ], in, nSamplesIn );
-
-            max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 \
-   );         /* + 1 because 2x upsampling */
-            out = silk_resampler_private_IIR_FIR_INTERPOL( out, \
-   buf, max_index_Q16, index_increment_Q16 );
-            in += nSamplesIn;
-            inLen -= nSamplesIn;
-
-            if( inLen > 0 ) {
-                /* More iterations to do; copy last part of \
-   filtered signal to beginning of buffer */
-   -            silk_memcpy( buf, &buf[ nSamplesIn << 1 ], \
-   RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
-   +            silk_memmove( buf, &buf[ nSamplesIn << 1 ], \
-   RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
-            } else {
-                break;
-            }
-        }
-
-        /* Copy last part of filtered signal to the state for \
-   the next call */
-   -    silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], \
-   RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
-   +    silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], \
-   RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
-    }
-
-   Note: due to RFC formatting conventions, lines exceeding the column
-   width in the patch above are split using a backslash character.  The
-   backslashes at the end of a line and the white space at the beginning
-   of the following line are not part of the patch.  A properly
-   formatted patch including the three changes above is available at
-   <https://jmvalin.ca/misc_stuff/opus_update.patch>.  (EDITOR: change
-   to an ietf.org link when ready)
-
-6.  Integer wrap-around in inverse gain computation
-
-   It was discovered through decoder fuzzing that some bitstreams could
-   produce integer values exceeding 32-bits in
-   LPC_inverse_pred_gain_QA(), causing a wrap-around.  Although the
-   error is harmless in practice, the C standard considers the behavior
-   as undefined, so the following patch to line 87 of silk/
-   LPC_inv_pred_gain.c detects values that do not fit in a 32-bit
-   integer and considers the corresponding filters unstable:
-
-
-
-Valin & Vos              Expires April 24, 2017                 [Page 5]
-

-Internet-Draft                 Opus Update                  October 2016
-
-
-           /* Update AR coefficient */
-           for( n = 0; n < k; n++ ) {
-  -            tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( \
-  Aold_QA[ k - n - 1 ], rc_Q31, 31 );
-  -            Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q );
-  +            opus_int64 tmp64;
-  +            tmp_QA = silk_SUB_SAT32( Aold_QA[ n ], MUL32_FRAC_Q( \
-  Aold_QA[ k - n - 1 ], rc_Q31, 31 ) );
-  +            tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( tmp_QA, \
-  rc_mult2 ), mult2Q);
-  +            if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
-  +               return 0;
-  +            }
-  +            Anew_QA[ n ] = ( opus_int32 )tmp64;
-           }
-
-7.  Integer wrap-around in LSF decoding
-
-   It was discovered -- also from decoder fuzzing -- that an integer
-   wrap-around could occur when decoding line spectral frequency
-   coefficients from extreme bitstreams.  The end result of the wrap-
-   around is an illegal read access on the stack, which the authors do
-   not believe is exploitable but should nonetheless be fixed.  The
-   following patch to line 137 of silk/NLSF_stabilize.c prevents the
-   problem:
-
-              /* Keep delta_min distance between the NLSFs */
-            for( i = 1; i < L; i++ )
-   -            NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], \
-   NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
-   +            NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], \
-   silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) );
-
-            /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
-
-8.  Cap on Band Energy
-
-   On extreme bit-streams, it is possible for log-domain band energy
-   levels to exceed the maximum single-precision floating point value
-   once converted to a linear scale.  This would later cause the decoded
-   values to be NaN, possibly causing problems in the software using the
-   PCM values.  This can be avoided with the following patch to line 552
-   of celt/quant_bands.c:
-
-
-
-
-
-
-
-
-Valin & Vos              Expires April 24, 2017                 [Page 6]
-

-Internet-Draft                 Opus Update                  October 2016
-
-
-          {
-             opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands],
-                             SHL16((opus_val16)eMeans[i],6));
-   +         lg = MIN32(QCONST32(32.f, 16), lg);
-             eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
-          }
-          for (;i<m->nbEBands;i++)
-
-9.  Hybrid Folding
-
-   When encoding in hybrid mode at low bitrate, we sometimes only have
-   enough bits to code a single CELT band (8 - 9.6 kHz).  When that
-   happens, the second band (CELT band 18, from 9.6 to 12 kHz) cannot
-   use folding because it is wider than the amount already coded, and
-   falls back to LCG noise.  Because it can also happen on transients
-   (e.g. stops), it can cause audible pre-echo.
-
-   To address the issue, we change the folding behavior so that it is
-   never forced to fall back to LCG due to the first band not containing
-   enough coefficients to fold onto the second band.  This is achieved
-   by simply repeating part of the first band in the folding of the
-   second band.  This changes the code in celt/bands.c around line 1237:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Valin & Vos              Expires April 24, 2017                 [Page 7]
-

-Internet-Draft                 Opus Update                  October 2016
-
-
-            b = 0;
-         }
-
-  -      if (resynth && M*eBands[i]-N >= M*eBands[start] && \
-  (update_lowband || lowband_offset==0))
-  +      if (resynth && (M*eBands[i]-N >= M*eBands[start] || \
-  i==start+1) && (update_lowband || lowband_offset==0))
-               lowband_offset = i;
-
-  +      if (i == start+1)
-  +      {
-  +         int n1, n2;
-  +         int offset;
-  +         n1 = M*(eBands[start+1]-eBands[start]);
-  +         n2 = M*(eBands[start+2]-eBands[start+1]);
-  +         offset = M*eBands[start];
-  +         /* Duplicate enough of the first band folding data to \
-  be able to fold the second band.
-  +            Copies no data for CELT-only mode. */
-  +         OPUS_COPY(&norm[offset+n1], &norm[offset+2*n1 - n2], n2-n1);
-  +         if (C==2)
-  +            OPUS_COPY(&norm2[offset+n1], &norm2[offset+2*n1 - n2], \
-  n2-n1);
-  +      }
-  +
-         tf_change = tf_res[i];
-         if (i>=m->effEBands)
-         {
-
-   as well as line 1260:
-
-             fold_start = lowband_offset;
-             while(M*eBands[--fold_start] > effective_lowband);
-             fold_end = lowband_offset-1;
-   -         while(M*eBands[++fold_end] < effective_lowband+N);
-   +         while(++fold_end < i && M*eBands[fold_end] < \
-   effective_lowband+N);
-             x_cm = y_cm = 0;
-             fold_i = fold_start; do {
-               x_cm |= collapse_masks[fold_i*C+0];
-
-
-   The fix does not impact compatibility, because the improvement does
-   not depend on the encoder doing anything special.  There is also no
-   reasonable way for an encoder to use the original behavior to improve
-   quality over the proposed change.
-
-
-
-
-
-Valin & Vos              Expires April 24, 2017                 [Page 8]
-

-Internet-Draft                 Opus Update                  October 2016
-
-
-10.  Downmix to Mono
-
-   The last issue is not strictly a bug, but it is an issue that has
-   been reported when downmixing an Opus decoded stream to mono, whether
-   this is done inside the decoder or as a post-processing step on the
-   stereo decoder output.  Opus intensity stereo allows optionally
-   coding the two channels 180-degrees out of phase on a per-band basis.
-   This provides better stereo quality than forcing the two channels to
-   be in phase, but when the output is downmixed to mono, the energy in
-   the affected bands is cancelled sometimes resulting in audible
-   artefacts.
-
-   As a work-around for this issue, the decoder MAY choose not to apply
-   the 180-degree phase shift when the output is meant to be downmixed
-   (inside or outside of the decoder).
-
-11.  New Test Vectors
-
-   Changes in Section 9 and Section 10 have sufficient impact on the
-   testvectors to make them fail.  For this reason, this document also
-   updates the Opus test vectors.  The new test vectors now include two
-   decoded outputs for the same bitstream.  The outputs with suffix 'm'
-   do not apply the CELT 180-degree phase shift as allowed in
-   Section 10, while the outputs without the suffix do.  An
-   implementation is compliant as long as it passes either set of
-   vectors.
-
-   In addition, any Opus implementation that passes the original test
-   vectors from RFC 6716 [RFC6716] is still compliant with the Opus
-   specification.  However, newer implementations SHOULD be based on the
-   new test vectors rather than the old ones.
-
-   The new test vectors are located at <https://jmvalin.ca/misc_stuff/
-   opus_newvectors.tar.gz>.  (EDITOR: change to an ietf.org link when
-   ready)
-
-12.  IANA Considerations
-
-   This document makes no request of IANA.
-
-   Note to RFC Editor: this section may be removed on publication as an
-   RFC.
-
-13.  Acknowledgements
-
-   We would like to thank Juri Aedla for reporting the issue with the
-   parsing of the Opus padding.
-
-
-
-
-Valin & Vos              Expires April 24, 2017                 [Page 9]
-

-Internet-Draft                 Opus Update                  October 2016
-
-
-14.  References
-
-   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
-              Requirement Levels", BCP 14, RFC 2119,
-              DOI 10.17487/RFC2119, March 1997,
-              <http://www.rfc-editor.org/info/rfc2119>.
-
-   [RFC6716]  Valin, JM., Vos, K., and T. Terriberry, "Definition of the
-              Opus Audio Codec", RFC 6716, DOI 10.17487/RFC6716,
-              September 2012, <http://www.rfc-editor.org/info/rfc6716>.
-
-Authors' Addresses
-
-   Jean-Marc Valin
-   Mozilla Corporation
-   331 E. Evelyn Avenue
-   Mountain View, CA  94041
-   USA
-
-   Phone: +1 650 903-0800
-   Email: jmvalin@jmvalin.ca
-
-
-   Koen Vos
-   vocTone
-
-   Email: koenvos74@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Valin & Vos              Expires April 24, 2017                [Page 10]
-
-

- Html markup produced by rfcmarkup 1.120, available from - https://tools.ietf.org/tools/rfcmarkup/ - -
- - diff --git a/opus.spec b/opus.spec index feeef67..a5028c8 100644 --- a/opus.spec +++ b/opus.spec @@ -10,7 +10,7 @@ URL: https://www.opus-codec.org/ Source0: http://downloads.xiph.org/releases/%{name}/%{name}-%{version}%{?candidate:-%{candidate}}.tar.gz # This is the final IETF Working Group RFC Source1: http://tools.ietf.org/rfc/rfc6716.txt -Source2: https://tools.ietf.org/html/draft-ietf-codec-opus-update-04 +Source2: http://tools.ietf.org/rfc/rfc8251.txt BuildRequires: doxygen @@ -57,7 +57,7 @@ make check %{_libdir}/libopus.so.* %files devel -%doc README doc/html rfc6716.txt draft-ietf-codec-opus-update-04 +%doc README doc/html rfc6716.txt rfc8251.txt %{_includedir}/opus %{_libdir}/libopus.so %{_libdir}/pkgconfig/opus.pc diff --git a/rfc8251.txt b/rfc8251.txt new file mode 100644 index 0000000..d240353 --- /dev/null +++ b/rfc8251.txt @@ -0,0 +1,675 @@ + + + + + + +Internet Engineering Task Force (IETF) JM. Valin +Request for Comments: 8251 Mozilla Corporation +Updates: 6716 K. Vos +Category: Standards Track vocTone +ISSN: 2070-1721 October 2017 + + + Updates to the Opus Audio Codec + +Abstract + + This document addresses minor issues that were found in the + specification of the Opus audio codec in RFC 6716. It updates the + normative decoder implementation included in Appendix A of RFC 6716. + The changes fix real and potential security-related issues, as well + as minor quality-related issues. + +Status of This Memo + + This is an Internet Standards Track document. + + This document is a product of the Internet Engineering Task Force + (IETF). It represents the consensus of the IETF community. It has + received public review and has been approved for publication by the + Internet Engineering Steering Group (IESG). Further information on + Internet Standards is available in Section 2 of RFC 7841. + + Information about the current status of this document, any errata, + and how to provide feedback on it may be obtained at + https://www.rfc-editor.org/info/rfc8251. + +Copyright Notice + + Copyright (c) 2017 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + + + + + + +Valin & Vos Standards Track [Page 1] + +RFC 8251 Opus Update October 2017 + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 3. Stereo State Reset in SILK . . . . . . . . . . . . . . . . . 3 + 4. Parsing of the Opus Packet Padding . . . . . . . . . . . . . 4 + 5. Resampler Buffer . . . . . . . . . . . . . . . . . . . . . . 4 + 6. Integer Wrap-Around in Inverse Gain Computation . . . . . . . 6 + 7. Integer Wrap-Around in LSF Decoding . . . . . . . . . . . . . 7 + 8. Cap on Band Energy . . . . . . . . . . . . . . . . . . . . . 7 + 9. Hybrid Folding . . . . . . . . . . . . . . . . . . . . . . . 8 + 10. Downmix to Mono . . . . . . . . . . . . . . . . . . . . . . . 9 + 11. New Test Vectors . . . . . . . . . . . . . . . . . . . . . . 9 + 12. Security Considerations . . . . . . . . . . . . . . . . . . . 11 + 13. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 11 + 14. Normative References . . . . . . . . . . . . . . . . . . . . 11 + Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 11 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 12 + +1. Introduction + + This document addresses minor issues that were discovered in the + reference implementation of the Opus codec. Unlike most IETF + specifications, RFC 6716 [RFC6716] defines Opus in terms of a + normative reference decoder implementation rather than from the + associated text description. Appendix A of that RFC includes the + reference decoder implementation, which is why only issues affecting + the decoder are listed here. An up-to-date implementation of the + Opus encoder can be found at . + + Some of the changes in this document update normative behavior in a + way that requires new test vectors. Only the C implementation is + affected, not the English text of the specification. This + specification remains fully compatible with RFC 6716 [RFC6716]. + + Note: Due to RFC formatting conventions, lines exceeding the column + width in the patch are split using a backslash character. The + backslashes at the end of a line and the white space at the beginning + of the following line are not part of the patch. Referenced line + numbers are approximations. A properly formatted patch including all + changes is available at and has a SHA-1 hash of + 029e3aa88fc342c91e67a21e7bfbc9458661cd5f. + + + + + + + + +Valin & Vos Standards Track [Page 2] + +RFC 8251 Opus Update October 2017 + + +2. Terminology + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and + "OPTIONAL" in this document are to be interpreted as described in + BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all + capitals, as shown here. + +3. Stereo State Reset in SILK + + The reference implementation does not reinitialize the stereo state + during a mode switch. The old stereo memory can produce a brief + impulse (i.e., single sample) in the decoded audio. This can be + fixed by changing silk/dec_API.c around line 72: + + + for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) { + ret = silk_init_decoder( &channel_state[ n ] ); + } + + silk_memset(&((silk_decoder *)decState)->sStereo, 0, + + sizeof(((silk_decoder *)decState)->sStereo)); + + /* Not strictly needed, but it's cleaner that way */ + + ((silk_decoder *)decState)->prev_decode_only_middle = 0; + + return ret; + } + + + This change affects the normative output of the decoder, but the + amount of change is within the tolerance and is too small to make the + test vector check fail. + + + + + + + + + + + + + + + + + + + + +Valin & Vos Standards Track [Page 3] + +RFC 8251 Opus Update October 2017 + + +4. Parsing of the Opus Packet Padding + + It was discovered that some invalid packets of a very large size + could trigger an out-of-bounds read in the Opus packet parsing code + responsible for padding. This is due to an integer overflow if the + signaled padding exceeds 2^31-1 bytes (the actual packet may be + smaller). The code can be fixed by decrementing the (signed) len + value, instead of incrementing a separate padding counter. This is + done by applying the following changes around line 596 of + src/opus_decoder.c: + + + /* Padding flag is bit 6 */ + if (ch&0x40) + { + - int padding=0; + int p; + do { + if (len<=0) + return OPUS_INVALID_PACKET; + p = *data++; + len--; + - padding += p==255 ? 254: p; + + len -= p==255 ? 254: p; + } while (p==255); + - len -= padding; + } + + + This packet-parsing issue is limited to reading memory up to about 60 + KB beyond the compressed buffer. This can only be triggered by a + compressed packet more than about 16 MB long, so it's not a problem + for RTP. In theory, it could crash a file decoder (e.g., Opus in + Ogg) if the memory just after the incoming packet is out of range, + but our attempts to trigger such a crash in a production application + built using an affected version of the Opus decoder failed. + +5. Resampler Buffer + + The SILK resampler had the following issues: + + 1. The calls to memcpy() were using sizeof(opus_int32), but the type + of the local buffer was opus_int16. + + + + + + + + +Valin & Vos Standards Track [Page 4] + +RFC 8251 Opus Update October 2017 + + + 2. Because the size was wrong, this potentially allowed the source + and destination regions of the memcpy() to overlap on the copy + from "buf" to "buf". We believe that nSamplesIn (number of input + samples) is at least fs_in_khZ (sampling rate in kHz), which is + at least 8. Since RESAMPLER_ORDER_FIR_12 is only 8, that should + not be a problem once the type size is fixed. + + 3. The size of the buffer used RESAMPLER_MAX_BATCH_SIZE_IN, but the + data stored in it was actually twice the input batch size + (nSamplesIn<<1). + + The code can be fixed by applying the following changes around line + 78 of silk/resampler_private_IIR_FIR.c: + + + + ) + { + silk_resampler_state_struct *S = \ + (silk_resampler_state_struct *)SS; + opus_int32 nSamplesIn; + opus_int32 max_index_Q16, index_increment_Q16; + - opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + \ + RESAMPLER_ORDER_FIR_12 ]; + + opus_int16 buf[ 2*RESAMPLER_MAX_BATCH_SIZE_IN + \ + RESAMPLER_ORDER_FIR_12 ]; + + /* Copy buffered samples to start of buffer */ + - silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 \ + * sizeof( opus_int32 ) ); + + silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 \ + * sizeof( opus_int16 ) ); + + /* Iterate over blocks of frameSizeIn input samples */ + index_increment_Q16 = S->invRatio_Q16; + while( 1 ) { + nSamplesIn = silk_min( inLen, S->batchSize ); + + /* Upsample 2x */ + silk_resampler_private_up2_HQ( S->sIIR, &buf[ \ + RESAMPLER_ORDER_FIR_12 ], in, nSamplesIn ); + + max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 \ + ); /* + 1 because 2x upsampling */ + out = silk_resampler_private_IIR_FIR_INTERPOL( out, \ + buf, max_index_Q16, index_increment_Q16 ); + in += nSamplesIn; + inLen -= nSamplesIn; + + + +Valin & Vos Standards Track [Page 5] + +RFC 8251 Opus Update October 2017 + + + if( inLen > 0 ) { + /* More iterations to do; copy last part of \ + filtered signal to beginning of buffer */ + - silk_memcpy( buf, &buf[ nSamplesIn << 1 ], \ + RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) ); + + silk_memmove( buf, &buf[ nSamplesIn << 1 ], \ + RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); + } else { + break; + } + } + + /* Copy last part of filtered signal to the state for \ + the next call */ + - silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], \ + RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) ); + + silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], \ + RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); + } + + +6. Integer Wrap-Around in Inverse Gain Computation + + It was discovered through decoder fuzzing that some bitstreams could + produce integer values exceeding 32 bits in + LPC_inverse_pred_gain_QA(), causing a wrap-around. The C standard + considers this behavior as undefined. The following patch around + line 87 of silk/LPC_inv_pred_gain.c detects values that do not fit in + a 32-bit integer and considers the corresponding filters unstable: + + + /* Update AR coefficient */ + for( n = 0; n < k; n++ ) { + - tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( \ + Aold_QA[ k - n - 1 ], rc_Q31, 31 ); + - Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q ); + + opus_int64 tmp64; + + tmp_QA = silk_SUB_SAT32( Aold_QA[ n ], MUL32_FRAC_Q( \ + Aold_QA[ k - n - 1 ], rc_Q31, 31 ) ); + + tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( tmp_QA, \ + rc_mult2 ), mult2Q); + + if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) { + + return 0; + + } + + Anew_QA[ n ] = ( opus_int32 )tmp64; + } + + + + + +Valin & Vos Standards Track [Page 6] + +RFC 8251 Opus Update October 2017 + + +7. Integer Wrap-Around in LSF Decoding + + It was discovered -- also from decoder fuzzing -- that an integer + wrap-around could occur when decoding bitstreams with extremely large + values for the high Line Spectral Frequency (LSF) parameters. The + end result of the wrap-around is an illegal read access on the stack, + which the authors do not believe is exploitable but should + nonetheless be fixed. The following patch around line 137 of silk/ + NLSF_stabilize.c prevents the problem: + + + /* Keep delta_min distance between the NLSFs */ + for( i = 1; i < L; i++ ) + - NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], \ + NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); + + NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], \ + silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) ); + + /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ + + +8. Cap on Band Energy + + On extreme bitstreams, it is possible for log-domain band energy + levels to exceed the maximum single-precision floating point value + once converted to a linear scale. This would later cause the decoded + values to be NaN (not a number), possibly causing problems in the + software using the PCM values. This can be avoided with the + following patch around line 552 of celt/quant_bands.c: + + + { + opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands], + SHL16((opus_val16)eMeans[i],6)); + + lg = MIN32(QCONST32(32.f, 16), lg); + eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4); + } + for (;inbEBands;i++) + + + + + + + + + + + + + +Valin & Vos Standards Track [Page 7] + +RFC 8251 Opus Update October 2017 + + +9. Hybrid Folding + + When encoding in hybrid mode at low bitrate, we sometimes only have + enough bits to code a single Constrained-Energy Lapped Transform + (CELT) band (8 - 9.6 kHz). When that happens, the second band (CELT + band 18, from 9.6 - 12 kHz) cannot use folding because it is wider + than the amount already coded and falls back to white noise. Because + it can also happen on transients (e.g., stops), it can cause audible + pre-echo. + + To address the issue, we change the folding behavior so that it is + never forced to fall back to Linear Congruential Generator (LCG) due + to the first band not containing enough coefficients to fold onto the + second band. This is achieved by simply repeating part of the first + band in the folding of the second band. This changes the code in + celt/bands.c around line 1237: + + + b = 0; + } + + - if (resynth && M*eBands[i]-N >= M*eBands[start] && \ + (update_lowband || lowband_offset==0)) + + if (resynth && (M*eBands[i]-N >= M*eBands[start] || \ + i==start+1) && (update_lowband || lowband_offset==0)) + lowband_offset = i; + + + if (i == start+1) + + { + + int n1, n2; + + int offset; + + n1 = M*(eBands[start+1]-eBands[start]); + + n2 = M*(eBands[start+2]-eBands[start+1]); + + offset = M*eBands[start]; + + /* Duplicate enough of the first band folding data to \ + be able to fold the second band. + + Copies no data for CELT-only mode. */ + + OPUS_COPY(&norm[offset+n1], &norm[offset+2*n1 - n2], n2-n1); + + if (C==2) + + OPUS_COPY(&norm2[offset+n1], &norm2[offset+2*n1 - n2], \ + n2-n1); + + } + + + tf_change = tf_res[i]; + if (i>=m->effEBands) + { + + + + + +Valin & Vos Standards Track [Page 8] + +RFC 8251 Opus Update October 2017 + + + as well as around line 1260: + + + fold_start = lowband_offset; + while(M*eBands[--fold_start] > effective_lowband); + fold_end = lowband_offset-1; + - while(M*eBands[++fold_end] < effective_lowband+N); + + while(++fold_end < i && M*eBands[fold_end] < \ + effective_lowband+N); + x_cm = y_cm = 0; + fold_i = fold_start; do { + x_cm |= collapse_masks[fold_i*C+0]; + + + + The fix does not impact compatibility, because the improvement does + not depend on the encoder doing anything special. There is also no + reasonable way for an encoder to use the original behavior to improve + quality over the proposed change. + +10. Downmix to Mono + + The last issue is not strictly a bug, but it is an issue that has + been reported when downmixing an Opus decoded stream to mono, whether + this is done inside the decoder or as a post-processing step on the + stereo decoder output. Opus intensity stereo allows optionally + coding the two channels 180 degrees out of phase on a per-band basis. + This provides better stereo quality than forcing the two channels to + be in phase, but when the output is downmixed to mono, the energy in + the affected bands is canceled, sometimes resulting in audible + artifacts. + + As a work-around for this issue, the decoder MAY choose not to apply + the 180-degree phase shift. This can be useful when downmixing to + mono inside or outside of the decoder (e.g., requested explicitly + from an API). + +11. New Test Vectors + + Changes in Sections 9 and 10 have sufficient impact on the test + vectors to make them fail. For this reason, this document also + updates the Opus test vectors. The new test vectors now include two + decoded outputs for the same bitstream. The outputs with suffix 'm' + do not apply the CELT 180-degree phase shift as allowed in + Section 10, while the outputs without the suffix do. An + implementation is compliant as long as it passes either set of + vectors. + + + + +Valin & Vos Standards Track [Page 9] + +RFC 8251 Opus Update October 2017 + + + Any Opus implementation that passes either the original test vectors + from RFC 6716 [RFC6716] or one of the new sets of test vectors is + compliant with the Opus specification. However, newer + implementations SHOULD be based on the new test vectors rather than + the old ones. + + The new test vectors are located at + . The SHA-1 hashes of the test vectors are: + + e49b2862ceec7324790ed8019eb9744596d5be01 testvector01.bit + b809795ae1bcd606049d76de4ad24236257135e0 testvector02.bit + e0c4ecaeab44d35a2f5b6575cd996848e5ee2acc testvector03.bit + a0f870cbe14ebb71fa9066ef3ee96e59c9a75187 testvector04.bit + 9b3d92b48b965dfe9edf7b8a85edd4309f8cf7c8 testvector05.bit + 28e66769ab17e17f72875283c14b19690cbc4e57 testvector06.bit + bacf467be3215fc7ec288f29e2477de1192947a6 testvector07.bit + ddbe08b688bbf934071f3893cd0030ce48dba12f testvector08.bit + 3932d9d61944dab1201645b8eeaad595d5705ecb testvector09.bit + 521eb2a1e0cc9c31b8b740673307c2d3b10c1900 testvector10.bit + 6bc8f3146fcb96450c901b16c3d464ccdf4d5d96 testvector11.bit + 338c3f1b4b97226bc60bc41038becbc6de06b28f testvector12.bit + f5ef93884da6a814d311027918e9afc6f2e5c2c8 testvector01.dec + 48ac1ff1995250a756e1e17bd32acefa8cd2b820 testvector02.dec + d15567e919db2d0e818727092c0af8dd9df23c95 testvector03.dec + 1249dd28f5bd1e39a66fd6d99449dca7a8316342 testvector04.dec + b85675d81deef84a112c466cdff3b7aaa1d2fc76 testvector05.dec + 55f0b191e90bfa6f98b50d01a64b44255cb4813e testvector06.dec + 61e8b357ab090b1801eeb578a28a6ae935e25b7b testvector07.dec + a58539ee5321453b2ddf4c0f2500e856b3966862 testvector08.dec + bb96aad2cde188555862b7bbb3af6133851ef8f4 testvector09.dec + 1b6cdf0413ac9965b16184b1bea129b5c0b2a37a testvector10.dec + b1fff72b74666e3027801b29dbc48b31f80dee0d testvector11.dec + 98e09bbafed329e341c3b4052e9c4ba5fc83f9b1 testvector12.dec + 1e7d984ea3fbb16ba998aea761f4893fbdb30157 testvector01m.dec + 48ac1ff1995250a756e1e17bd32acefa8cd2b820 testvector02m.dec + d15567e919db2d0e818727092c0af8dd9df23c95 testvector03m.dec + 1249dd28f5bd1e39a66fd6d99449dca7a8316342 testvector04m.dec + d70b0bad431e7d463bc3da49bd2d49f1c6d0a530 testvector05m.dec + 6ac1648c3174c95fada565161a6c78bdbe59c77d testvector06m.dec + fc5e2f709693738324fb4c8bdc0dad6dda04e713 testvector07m.dec + aad2ba397bf1b6a18e8e09b50e4b19627d479f00 testvector08m.dec + 6feb7a7b9d7cdc1383baf8d5739e2a514bd0ba08 testvector09m.dec + 1b6cdf0413ac9965b16184b1bea129b5c0b2a37a testvector10m.dec + fd3d3a7b0dfbdab98d37ed9aa04b659b9fefbd18 testvector11m.dec + 98e09bbafed329e341c3b4052e9c4ba5fc83f9b1 testvector12m.dec + + Note that the decoder input bitstream files (.bit) are unchanged. + + + +Valin & Vos Standards Track [Page 10] + +RFC 8251 Opus Update October 2017 + + +12. Security Considerations + + This document fixes two security issues reported on Opus that affect + the reference implementation in RFC 6716 [RFC6716]: CVE-2013-0899 + and CVE-2017-0381 + . CVE-2013-0899 + theoretically could have caused an information leak. The leaked + information would have gone through the decoder process before being + accessible to the attacker. The update in Section 4 fixes this. + CVE-2017-0381 could have resulted in a 16-bit out-of-bounds read from + a fixed location. The update in Section 7 fixes this. Beyond the + two fixed Common Vulnerabilities and Exposures (CVEs), this document + adds no new security considerations beyond those in RFC 6716 + [RFC6716]. + +13. IANA Considerations + + This document does not require any IANA actions. + +14. Normative References + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, + DOI 10.17487/RFC2119, March 1997, + . + + [RFC6716] Valin, JM., Vos, K., and T. Terriberry, "Definition of the + Opus Audio Codec", RFC 6716, DOI 10.17487/RFC6716, + September 2012, . + + [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC + 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, + May 2017, . + +Acknowledgements + + We would like to thank Juri Aedla for reporting the issue with the + parsing of the Opus padding. Thanks to Felicia Lim for reporting the + LSF integer overflow issue. Also, thanks to Tina le Grand, Jonathan + Lennox, and Mark Harris for their feedback on this document. + + + + + + + + + + + +Valin & Vos Standards Track [Page 11] + +RFC 8251 Opus Update October 2017 + + +Authors' Addresses + + Jean-Marc Valin + Mozilla Corporation + 331 E. Evelyn Avenue + Mountain View, CA 94041 + United States of America + + Phone: +1 650 903-0800 + Email: jmvalin@jmvalin.ca + + + Koen Vos + vocTone + + Email: koenvos74@gmail.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Valin & Vos Standards Track [Page 12] +