<?xml version="1.0"?>
<?xml-stylesheet href="docbook.xsl" type="text/xsl" ?>
<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="book_uhs_njq_bwb">
  <info>
    <title>Media Signing Specification</title>
    <titleabbrev>Media Signing</titleabbrev>
    <releaseinfo>25.12</releaseinfo>
    <author>
      <orgname>ONVIF™</orgname>
      <uri>www.onvif.org</uri>
    </author>
    <pubdate>December, 2025</pubdate>
    <mediaobject>
      <imageobject>
        <imagedata fileref="media/logo.png" contentwidth="60mm"/>
      </imageobject>
    </mediaobject>
    <copyright>
      <year>2022-2025</year>
      <holder>ONVIF™ All rights reserved.</holder>
    </copyright>
    <legalnotice>
      <para>Recipients of this document may copy, distribute, publish, or display this document so
        long as this copyright notice, license and disclaimer are retained with all copies of the
        document. No license is granted to modify this document.</para>
      <para>THIS DOCUMENT IS PROVIDED "AS IS," AND THE CORPORATION AND ITS MEMBERS AND THEIR
        AFFILIATES, MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
        LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
        NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THIS DOCUMENT ARE SUITABLE FOR ANY PURPOSE;
        OR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS,
        TRADEMARKS OR OTHER RIGHTS.</para>
      <para>IN NO EVENT WILL THE CORPORATION OR ITS MEMBERS OR THEIR AFFILIATES BE LIABLE FOR ANY
        DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR
        RELATING TO ANY USE OR DISTRIBUTION OF THIS DOCUMENT, WHETHER OR NOT (1) THE CORPORATION,
        MEMBERS OR THEIR AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR (2)
        SUCH DAMAGES WERE REASONABLY FORESEEABLE, AND ARISING OUT OF OR RELATING TO ANY USE OR
        DISTRIBUTION OF THIS DOCUMENT. THE FOREGOING DISCLAIMER AND LIMITATION ON LIABILITY DO NOT
        APPLY TO, INVALIDATE, OR LIMIT REPRESENTATIONS AND WARRANTIES MADE BY THE MEMBERS AND THEIR
        RESPECTIVE AFFILIATES TO THE CORPORATION AND OTHER MEMBERS IN CERTAIN WRITTEN POLICIES OF
        THE CORPORATION.</para>
    </legalnotice>
    <revhistory>
      <revision>
        <revnumber>24.12</revnumber>
        <date>Dec-2024</date>
        <author>
          <personname>Björn Völcker, Fredrik Svensson, Axel Keskikangas</personname>
        </author>
        <revremark>First release</revremark>
      </revision>
      <revision>
        <revnumber>25.06</revnumber>
        <date>Jun-2025</date>
        <author>
          <personname>Björn Völcker</personname>
        </author>
        <revremark>Clarify the difference between Firmware and Software version.</revremark>
      </revision>
      <revision>
        <revnumber>25.12</revnumber>
        <date>Dec-2025</date>
        <author>
          <personname>Björn Völcker</personname>
        </author>
        <revremark>Added a second timestamp to bitstream and removed specification version.
          Requires SEIs to be added in sequential order.</revremark>
      </revision>
    </revhistory>
  </info>
  <chapter xml:id="chapter_zhs_njq_bwb">
    <title>Scope</title>
    <para>This specification defines how media from ONVIF devices is signed to give a guarantee that
      the media has not been manipulated since it was transmitted from the device. This
      specification further defines how an ONVIF client should act at file export to preserve the
      signing feature, and also how an ONVIF client should validate the authenticity of a signed
      stream. Audio is outside of scope.</para>
  </chapter>
  <chapter xml:id="chapter_a3s_njq_bwb">
    <title>Normative references</title>
    <para>ITU-T Recommendation, H.264: Advanced video coding for generic audiovisual services</para>
    <para role="reference">&lt;<link xlink:href="https://www.itu.int/rec/T-REC-H.264" xmlns:xlink="http://www.w3.org/1999/xlink"/>&gt;</para>
    <para>ITU-T Recommendation, H.265: High effiency video coding</para>
    <para role="reference">&lt;<link xlink:href="https://www.itu.int/rec/T-REC-H.265" xmlns:xlink="http://www.w3.org/1999/xlink"/>&gt;</para>
    <para>ITU-T Recommendation X.660 (2011) | ISO/IEC 9834-1:2012, Information technology —
      Procedures for the operation of object identifier registration authorities — Part 1: General
      procedures and top arcs of the international object identifier tree</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://www.itu.int/rec/T-REC-X.660-201107-I/en"/>&gt;</para>
    <para>Global OID reference database</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://oid-info.com/"/>&gt;</para>
    <para>IETF RFC 6234 - US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)</para>
    <para role="reference">&lt;<link xlink:href="http://tools.ietf.org/html/rfc6234" xmlns:xlink="http://www.w3.org/1999/xlink"/>&gt;</para>
    <para>Reference implementation of this specification</para>
    <para role="reference">&lt;<link xlink:href="https://github.com/onvif/signed-media-framework" xmlns:xlink="http://www.w3.org/1999/xlink"/>&gt;</para>
  </chapter>
  <chapter xml:id="chapter_b3s_njq_bwb">
    <title>Terms and Definitions</title>
    <section xml:id="section_c3s_njq_bwb">
      <title>Definitions</title>
      <informaltable>
        <tgroup cols="2">
          <colspec colname="c1" colwidth="24*"/>
          <colspec colname="c2" colwidth="76*"/>
          <tbody valign="top">
            <row>
              <entry align="left">
                <para>Document</para>
              </entry>
              <entry align="left">
                <para>A document in this specification refers to a codec specific document that
                  includes hashes of all media frames since previous signing occasion together with
                  other metadata. For H.264 and H.265 a document is encoded into a SEI frame.</para>
              </entry>
            </row>
            <row>
              <entry align="left">
                <para>Certificate</para>
              </entry>
              <entry align="left">
                <para>A certificate as used in this specification binds a public key to a subject
                  entity. The certificate is digitally signed by the certificate issuer to allow for
                  verifying its authenticity. In order to verify a certificate, one might need to
                  include one or more intermediate certificates.</para>
              </entry>
            </row>
            <row>
              <entry align="left">
                <para>Signature</para>
              </entry>
              <entry align="left">
                <para>A digital signature or digital signature scheme is a mathematical scheme for
                  demonstrating the authenticity of a digital message or document.</para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>
    <section xml:id="section_d3s_njq_bwb">
      <title>Abbreviations</title>
      <informaltable>
        <tgroup cols="2">
          <colspec colname="c1" colwidth="24*"/>
          <colspec colname="c2" colwidth="76*"/>
          <tbody valign="top">
            <row>
              <entry valign="middle">
                <para>AU</para>
              </entry>
              <entry valign="middle">
                <para>Access Unit</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>GOP</para>
              </entry>
              <entry valign="middle">
                <para>Group Of Pictures</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>IDR</para>
              </entry>
              <entry valign="middle">
                <para>Instantaneous Decoding Refresh</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>NAL</para>
              </entry>
              <entry valign="middle">
                <para>Network Abstraction Layer</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>VCL</para>
              </entry>
              <entry valign="middle">
                <para>Video Coding Layer</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>SEI</para>
              </entry>
              <entry valign="middle">
                <para>Supplementary Enhancement Information</para>
              </entry>
            </row>
            <row>
              <entry valign="middle">
                <para>TLV</para>
              </entry>
              <entry valign="middle">
                <para>Type-Length-Value</para>
              </entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
    </section>
  </chapter>
  <chapter xml:id="chapter_e3s_njq_bwb">
    <title>Overview</title>
    <para>Media Signing is the process of adding cryptographic signatures to captured media as part
      of the codec format. By adding these signatures, the media can be protected against
      manipulation (tampering) and the authenticity can be validated.</para>
    <para>The public key, that is used to verify the signatures, is also included in the media, as
      well as certificates to verify the public key. The CA certificate necessary to verify the
      certificates is not included and has to be acquired from an external trusted source.</para>
  </chapter>
  <chapter xml:id="chapter_f3s_njq_bwb">
    <title>Signed Video</title>
    <para>A video consists of picture frames displayed at a certain frame rate. If these frames are
      transmitted or stored for later use and displayed by a third party it is valuable to be able
      to prove that the video has not been manipulated since the time of signing.</para>
    <para>In brief, the principle of signing documents is used, that is, collect information and
      sign the information using a Private signing key. Then, packetize the produced signature
      together with the collected information. For validation, verifiy the signature using the
      Public Key. If successful, the content in the document can be used to validate the
      authenticity of the video. In Media Signing, the Public key is wrapped in a chain of
      certificates without its root CA certificate. Therefore, the Public key needs to be verified
      before use. Verify the certificates with the corresponding CA certificate, followed by Public
      key verification with.</para>
    <para>On a high level, <emphasis>Signed Video</emphasis> hashes encoded video frames and on a
      regular basis creates a <code>document</code> representing these hashes together with some
      additional metadata and signs that <code>document</code>. This signature, together with the
        <code>document</code>, is added to the video using Supplementary Enhancement Information
      (SEI) frames.</para>
    <figure xml:id="signedvideofig">
      <title>Signed video overview</title>
      <mediaobject>
        <imageobject>
          <imagedata fileref="media/MediaSigning/signed_video.svg" contentwidth="170mm"/>
        </imageobject>
      </mediaobject>
    </figure>
    <section xml:id="section_g3s_njq_bwb">
      <title>Limitations</title>
      <para><emphasis role="bold">Codecs</emphasis>. <emphasis>Signed Video</emphasis> is defined
        for the H.264 and H.265 video codec formats, for full details see references.
        Therefore, most of the description uses the Network Abstraction Layer (NAL) concept.
        For simplicity, hashing is done on NAL Units
        instead of full frame data. One frame may be split into multiple NAL Units and therefore
        generating multiple hashes per frame. Note that raw video is not covered, since there are
        no means to add signatures within the video format. There exists other codec standards
        where the same technique can be applied though, but the specification considers H.264 and
        H.265.</para>
      <para><emphasis role="bold">Signing frequency</emphasis>. Signing is done upon transition
        between two Group of Pictures (GOPs), that is, triggered by an IDR frame. For short GOP
        lengths, the time between two GOP transitions may be shorter than the time it takes to
        perform the signing. The standard allows the device to sign multiple GOPs if necessary.
        This is described in Section <xref linkend="section_signing_multiple_gops"/>.
        For very long, or infinite, GOPs the duration between signatures can be too long for
        practical usage. Therefore, the device is recommended to sign partial GOPs; See Section
        <xref linkend="section_signing_partial_gops"/>.</para>
      <para><emphasis role="bold">Frame drops and packet losses</emphasis>. Adding a list of
        hashes of each NAL Unit combats the problem of lost frames, but cannot solve packet
        losses unless the affected NAL Unit is completely removed from the stream. To lower the
        risk of losing packets within a SEI frame, the specification allows the device to add
        redundancy by transmitting the same SEI multiple times; See Section
        <xref linkend="section_y3s_njq_bwb"/> below.</para>
      <para><emphasis role="bold">Hashing algorithms</emphasis>. Hashing algorithms, for example
        those specififed in RFC 6234, are generally used to compute a fixed length
        hash value from any long input string. Hashing is used in two contexts; 1)
        to get a short representation of each NAL Unit to put in a list, and 2) as message digest
        when generating signatures. Note that these two can be different. The same hashing
        algorithms have to be used in both the device and the client. The device specifies which
        hashing algorithms were used, which for example limits the ability for the client to put
        extra security on some videos.</para>
      <para><emphasis role="bold">Signing algorithm</emphasis>. The standard specifies the signing
        algorithm through its OID as definied by the relevant authority or searchable in the global
        OID reference database. Signing should be done in a trusted environment and there are
        usually limitations to which signing algorithms are supported. This limits the scope, and
        the device decides which to use.</para>
      <para><emphasis role="bold">Bitrate increase</emphasis>. Adding SEI frames to the encoded
        video increases the bitrate. The list of NAL Unit hashes is the main contribution.
        Therefore, it is recommended to consider a hashing algorithm that produces reasonably large
        hashes, e.g., SHA256. Note that the main security lies in the hash used to generate the
        signature and not the hash used to represent the NAL Unit. The device has an option to
        select a low bitrate mode; See Section <xref linkend="section_low_bitrate_mode"/>.</para>
    </section>
    <section>
      <title>Basic rules for the device when signing a video</title>
      <para>The procedure of signing a video stream and producing SEI frames, can be described by a
        set of rules.
        <itemizedlist>
          <listitem>
            <para>The NAL Unit types below shall be hashed</para>
            <para>All VCL NAL Units, that is, slices of IDR-, P- and B-frames.</para>
            <para>All SEI frames generated according to this specification, if not including a
              signature.</para>
            <para>A NAL Unit is hashed from first byte, excluding start code, to last written byte
              stop bit inclusive.</para>
          </listitem>
          <listitem>
            <para>Every GOP shall be associated with at least one SEI frame</para>
            <para>Long GOPs are recommended to be split into partial GOPs.</para>
          </listitem>
          <listitem>
            <para>Every partial GOP shall be signed</para>
          </listitem>
          <listitem>
            <para>Every SEI shall be linked with the first VCL NAL Unit of the previous partial
              or complete GOP.</para>
            <para>This is necessary to secure the order of frames from tampering.</para>
          </listitem>
          <listitem>
            <para>The generated SEIs shall be added to the stream in sequence order.</para>
          </listitem>
        </itemizedlist>
      </para>
    </section>
    <section xml:id="section_h3s_njq_bwb">
      <title>Detailed description on how the device generates SEI frames including
        signatures</title>
      <para>The H.264 and H.265 codec formats, as specified in referenced documents, allows the user
        to add arbitrary data to a stream through SEI frames of type user data unregistered.
        <emphasis>Signed Video</emphasis> puts the produced signatures and additional metadata in such frames.
        These SEI frames are ignored by the decoder and will therefore not affect the video rendering.
        One obvious drawback is that it is easy to change the video from signed to unsigned by dropping
        these SEI frames. In some cases this can also be beneficial. For example, if the user is no
        longer interested in its authenticity, the SEI frames can be removed and thereby reducing the bitrate.
        It is out of scope to protect against lost SEI frames. Validating a video where SEIs have been lost or
        removed will anyhow be marked as not authentic, or unsigned (if no SEIs are present).</para>
      <para>All operations are done on the encoded video stream consisting of NAL Units.
        <emphasis role="italic">Signed Video</emphasis> operates therefore on NAL Units.
        Note that it is not necessarily a one-to-one correspondance between frames and NAL Units. A
        frame split into slices (multiple NAL Units) will generate multiple hashes. In this
        specification, unless explicitly stated, hashing a frame means hashing a NAL Unit.</para>
      <para>All VCL NAL Units shall be hashed. In addition, all SEI frames, generated by ONVIF
        Media Signing shall also be hashed accordingly, unless the SEI includes a signature.</para>
      <para>Some non-VCL NAL Units have no or limited impact on the visual video and are ignored:
        <itemizedlist>
          <listitem>
            <para>SPS/PPS/VPS</para>
            <para>The presence of these NAL Units are not consistent. They can for example be sent
              once in the beginning of a stream and stored at client side to add back when exporting
              to file. This is a correct process, but affects the authenticity since Signed Video
              requires the order to be preserved, unless handled separately. There are parts in
              these NAL Units that can change the video behavior.</para>
          </listitem>
          <listitem>
            <para>AUD</para>
            <para>The Access Unit Delimiter (AUD) is simply a NAL Unit header used in Access Unit
              (AU) video streams, c.f., bytestream. This NAL Unit has no impact on the video and can
              safely be ignored. By ignoring them, the authenticity is preserved when converting
              between AU streams and bytestreams.</para>
          </listitem>
          <listitem>
            <para>SEIs other than Signed Video specific</para>
            <para>There are various types of SEI frames; See the H.264 and H.265 standards. In general,
              these SEI frames include information that has no visible impact on the video. Further,
              some of them can correctly be added to, or removed from, the stream at any point in
              time. This makes it difficult to handle from an authenticity point of view since the
              presence and order is important. Therefore, all other SEI frames than those described
              in this specification are ignored.</para>
          </listitem>
        </itemizedlist>
      </para>
      <para>Note that these frame types can still affect the visual aspect of a video, but are
        excluded until a there is a solution for it.</para>
    </section>
    <section xml:id="section_i3s_njq_bwb">
      <title>Signing a GOP</title>
      <para>A GOP is defined as all frames between two IDR frames, including the first IDR. Frames
        between these IDRs are prediction frames and can be either P- or B-frames. Without loss of
        generality, both of these are throughout the text denoted P-frames. Further, for simplicity
        IDRs are referred to as I-frames in this context.</para>
      <para>Each NAL Unit, except SEI-frames (see below) and those ignored (see above), is hashed
        in a linked manner. Since every P-frame directly or indirectly refers to the I-frame
        starting the GOP they are linked together. If the I-frame is modified it indirectly
        modifies the P-frames. Therefore, each P-frame is hashed together with the dependent
        I-frame.</para>
      <para>SEI-frames are hashed individually. The benefit is that the hash becomes independent
        of any I-frame. The SEI-frame content may then be verified and trusted even if an I-frame
        suffer from, for example, packet loss.</para>
      <para><xref linkend="linkedhashesfig"/> illustrates the linking procedure where a
        frame is encaptured in a single NAL Unit. The hash of the IDR-frame is stored and used to
        generate a second hash together with the hash of each P-frame in the GOP.</para>
      <figure xml:id="linkedhashesfig">
        <title>Linked hashes</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="media/MediaSigning/LinkedHashes1To1.svg" contentwidth="150mm"/>
          </imageobject>
        </mediaobject>
      </figure>
      <para><xref linkend="linkedhashesfig2"/> illustrates the linking procedure where each frame is
        encaptured in multiple NAL Units. The hash of the primary slice (dark red) of the I-frame is
        stored as an anchor hash and used to generate a second hash together with any other hash in
        the GOP. Note that the other NAL Units (non-primary slices) of the I-frame are hashed in
        this linked manner. In the example in <xref linkend="linkedhashesfig2"/>, there is one primary slice (dark red) and
        one non-primary slice NAL Unit (light red) illustrating the linking procedure where a frame
        is encaptured in multiple NAL Units. The hash of the primary slice of the I-frame is stored
        and used to generate a second hash together with any other hash in the GOP. Note that the
        other NAL Units of the I-frame are also hashed in this linked manner.</para>
      <figure xml:id="linkedhashesfig2">
        <title>Linked hashes, multiple NAL Units per frame</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="media/MediaSigning/LinkedHashes.svg" contentwidth="150mm"/>
          </imageobject>
        </mediaobject>
      </figure>
      <para>Let <code>H(F)</code> denote the hash of a NAL Unit <code>F</code>, and <code>h_anch =
          H(I)</code> is the hash of the leading I-frame in a GOP and used as anchor (linked hash).
        Then each frame in a GOP is hashed according to <code>hash(F) = H(h_anch, H(F))</code>,
        where <code>h_anch</code> and <code>H(F)</code> shall be hashed as if they were aligned in
        memory. All hashes are collected in a list and together with some metadata forms a
          <code>document</code>, which later will be signed.</para>
      <para>All NAL Unit data, from the NAL Unit header to the last byte, including the stop bit,
        shall be hashed. The start code is excluded when hashing.</para>
      <para>If the I-frame is sliced into multiple NAL Units, the hash of the primary slice shall
        be used as <code>h_anch = H(Iprimaryslice)</code>. The other NAL Units of the I-frame shall
        be hashed in the linked manner described above.</para>
      <para>The NAL Units shall be hashed in the same order as the encoder emits them, that is, in
        decoding order. For example, consider 4 consecutive images with data D1, D2, D3, D4.
        Let the encoder use a GOP structure with two B-frames, which in presentation order would be
        I-B-B-P. The order out from the encoder becomes I1-P4-B2-B3, which also is the order of
        which they shall be hashed and put in the list of hashes
        [h_ach, hash(P4), hash(B2), hash(B3)].</para>
      <para>A hash (<code>gophash</code>) of the list of hashes is added to metadata, <code>gophash
          = H(h_anch, hash(NALUnit1), hash(NALUnit2), ..., hash(NALUnitN))</code>. The
          <code>gophash</code> simplifies validation, since verifying each hash in the list of
        hashes is only necessary when verification of the <code>gophash</code> fails. Another
        benefit is that the bytestream is prepared for the future, where a low-bitrate alternative
        can be added by omitting the list of hashes.</para>
      <para>To preserve the order of GOPs the hash of the I-frame of the previous GOP is also added
        to metadata, that is, <code>hash(Iprevious) = h_anch_previous</code>. For the very first GOP
        a static and pre-defined hash shall be used; See the TLV section below.</para>
      <para>This <code>document</code> is then signed to produce a signature as <code>signature =
          sign(H(document))</code> and together with the <code>document</code> itself added to the
        stream in a SEI, that is, SEI = <code>document + signature</code>. The next GOP is initiated
        with a new <code>h_anch</code> using the very same I-frame that triggered the end of current
        GOP.</para>
      <para><xref linkend="signingdiagram"/> illustrates the overall signing
        procedure.</para>
      <figure xml:id="signingdiagram">
        <title>Signing Flow Chart</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="media/MediaSigning/SigningDiagram.svg" contentwidth="150mm"/>
          </imageobject>
        </mediaobject>
      </figure>
      <section>
        <title>Example</title>
        <para>The following figures show a typical example where each GOP is signed. In this example
          the GOP is 8 frames long where each I-frame (grey box with letter 'I') marks the start of
          a GOP, followed by 7 P-frames (white box with letter 'P'). Each I-frame triggers a signing
          procedure by generating a SEI (Supplemant Enhancement Information) frame of type "user
          data unregistered". Information, such as hashes from the frames, of the previous GOP is
          put in this SEI. The SEIs are colored yellow before being signed and green afterwards.
          SEIs (yellow) are hashed and sent to the signing hardware and added to the stream after
          signing (now green). The solid lines mark the frames that are signed/secured and the
          dashed line which frame the GOP is linked with to secure the order of GOPs. </para>
        <figure>
          <title>A generated SEI is hashed and sent to the signing hardware.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningGops01.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>Signing generally takes time. When ready, the signature is added to the SEI and injected attached to a frame into the stream.</para>
        <figure>
          <title>Signature is injected into the stream.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningGops02.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>A new I-frame triggers the next signing procedure.</para>
        <figure>
          <title>Next I-frame triggers next signing.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningGops03.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>When second GOP is signed, the signature is added to the SEI and injected attached to a frame into the stream.</para>
        <figure>
          <title>Injecting second signed SEI.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningGops04.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <figure>
          <title>An overview of which frames are secured by which SEI.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningGops07.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
      </section>
    </section>
    <section xml:id="section_signing_multiple_gops">
      <title>Signing multiple GOPs</title>
      <para>As mentioned in the Limitation Section above, there are situations when signing each GOP
        is not feasible in real-time. The device has an option to decide to sign every X:th GOP to
        keep the stream signed.</para>
      <para>Generate a SEI for every GOP according to the Section above, but sign only every X:th
        GOP. That is, every X:th SEI includes a Signature TLV.</para>
      <para>All, by this specification, generated SEI frames without a signature shall be hashed and
        added to the list of NAL Unit hashes. Note that they shall be hashed in the same order as
        they appear in the stream.</para>
      <para>The SEI frames shall be added in the exact order they are generated, regardless of their readiness.
        For example, a SEI frame without a signature that is ready before the previous
        signed SEI is, cannot be added until the signed SEI is completed.</para>
      <section>
        <title>Example</title>
        <para>The following example figures show how multiple short GOPs can be signed. The yellow
          boxes are used to illustrate unsigned SEIs and green boxes are signed SEIs.</para>
        <para><xref linkend="smg01"/> and <xref linkend="smg02"/> show how an I-frame starts a new GOP and a SEI representing the previous GOP is generated.
          These SEIs are not signed and can be injected to the stream instantly.</para>
        <figure xml:id="smg01">
          <title>Unsigned SEI of first I-frame.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningMultipleGops01.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <figure xml:id="smg02">
          <title>Unsigned SEI of second I-frame.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningMultipleGops02.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para><xref linkend="smg01"/> shows that after generating the SEI representing GOP 3, it is sent to the signing hardware.</para>
        <figure xml:id="smg03">
          <title>Signing SEI of GOP 3.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningMultipleGops03.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>While the third SEI is being signed, a SEI representing GOP 4 is generated and waiting to be injected into the stream as shown in <xref linkend="smg04"/>.</para>
        <figure xml:id="smg04">
          <title>Pending injection of SEI representing GOP 4.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningMultipleGops04.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>When the signature is ready it is added to the corresponding SEI and injected to the stream as shown in <xref linkend="smg05"/>.</para>
        <figure xml:id="smg05">
          <title>In order injection of signed SEI.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningMultipleGops05.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <figure>
          <title>Signing multiple GOPs 6</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningMultipleGops06.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>Finally <xref linkend="smg07"/> and <xref linkend="smg08"/> provide an overview of
          which frames are secured by which SEI. In the case of <xref linkend="smg07"/> the SEIs
          have been prepended to the same frame that triggered the SEI while in the case of <xref linkend="smg08"/> the SEIs have been added to the stream on the next available
          instance.</para>
        <figure xml:id="smg07">
          <title>Overview when SEIs are prepended.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningMultipleGops07.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <figure xml:id="smg08">
          <title>Overview when SEIs are added on the next available instance.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningMultipleGops08.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
      </section>
    </section>
    <section xml:id="section_signing_partial_gops">
      <title>Signing partial GOPs</title>
      <para>As mentioned in the Limitation Section above, very long, or even infinite, GOPs puts the
        validation side in an unacceptable situation since the duration between signatures is far to
        long. The device has an option to decide to force signing if the GOP has not ended in a
        reasonable time. It is recommended to split a GOP into partial GOPs if the GOP duration is
        longer than 5 seconds.</para>
      <para>Generate a SEI for every partial GOP according to the Section above and sign it.</para>
      <para>Note that hashing NAL Units use the same anchor hash across partial GOPs. The anchor
        hash is only reset upon an IDR, that is, when there is a new GOP.</para>
      <section>
        <title>Example</title>
        <para>The following example figures shows how long GOPs can be signed by using multiple
          SEIs.</para>
        <para>In <xref linkend="spg01"/> the number of NAL Units since the I-frame reached 7 which generates a first SEI that is hashed and sent to the signing hardware. SEI of partial GOP 1</para>
        <figure xml:id="spg01">
          <title>First SEI of partial GOP</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningPartialGops01.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>In <xref linkend="spg03"/> the signature is ready and added to the SEI (green) which is injected to the stream.</para>
        <figure xml:id="spg03">
          <title>Insert signed partial SEI</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningPartialGops03.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <figure xml:id="spg04">
          <title>SEI of partial GOP 2</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningPartialGops04.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para><xref linkend="spg05"/> shows that an I-frame triggers signing. A third SEI is generated that is hashed and sent to the signing hardware. SEI of partial GOP 3 put in queue for signing.</para>
        <figure xml:id="spg05">
          <title>I-Frame triggers SEI signing</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningPartialGops05.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>When the signature of the second SEI is ready, it is added to the corresponding SEI (green) and injected to the stream as shown in <xref linkend="spg07"/>.</para>
        <figure xml:id="spg07">
          <title>SEI of partial GOP 2 is injected to the stream.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningPartialGops07.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para><xref linkend="spg05"/> shows that the signature of the third SEI is now ready. It is added to the corresponding SEI (green) and injected to the stream. </para>
        <figure xml:id="spg08">
          <title>SEI of partial GOP 3 is injected to the stream.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningPartialGops08.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <figure xml:id="spg09">
          <title>SEI of partial GOP 4.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningPartialGops09.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>Finally <xref linkend="spg10"/>  provides an overview of which frames are secured by which SEI.</para>
        <figure xml:id="spg10">
          <title>Overview of which frames are secured by which SEI.</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="media/MediaSigning/SigningPartialGops10.svg" contentwidth="150mm"/>
            </imageobject>
          </mediaobject>
        </figure>
      </section>
    </section>
    <section xml:id="section_k3s_njq_bwb">
      <title>SEI format</title>
      <para>SEIs of type <emphasis role="italic">user data unregistered</emphasis> are used. These
        are organized as (excluding the 3-4 byte start code):</para>
      <para>
        <table frame="all">
          <title>User data unregistered SEI</title>
          <tgroup cols="5">
            <colspec colname="c1" colnum="1" colwidth="1*"/>
            <colspec colname="c2" colnum="2" colwidth="1*"/>
            <colspec colname="c3" colnum="3" colwidth="1*"/>
            <colspec colname="c4" colnum="4" colwidth="1*"/>
            <colspec colname="c5" colnum="5" colwidth="1*"/>
            <tbody>
              <row>
                <entry align="center">
                  <para>NAL Unit header</para>
                </entry>
                <entry align="center">
                  <para>payload size</para>
                </entry>
                <entry align="center">
                  <para>UUID</para>
                </entry>
                <entry align="center">
                  <para>payload</para>
                </entry>
                <entry align="center">
                  <para>stop bit</para>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </table>
      </para>
      <para>The UUID is used to put an <emphasis role="italic">ONVIF Signed Video</emphasis>
        identity to the SEI. UUID for Signed Video is
          <code>005bc93f-2d71-5e95-ada4-796f90877a6f</code>. The payload includes the metadata, the
        list of hashes and the signature, and is serialized in a TLV structure. The order of the
        added TLV tags is arbitrary except the signature tag which by definition has to come last.
        By definition the <code>document</code> includes everything from the NAL Unit header
        (inclusive) to the signature tag (exclusive), hence the entire frame is secured.</para>
      <para>
        <table frame="all">
          <title>Signed video SEI</title>
          <tgroup cols="8" align="center">
            <colspec colname="c1" colnum="1" colwidth="1*"/>
            <colspec colname="c2" colnum="2" colwidth="1*"/>
            <colspec colname="c3" colnum="3" colwidth="1*"/>
            <colspec colname="c4" colnum="4" colwidth="1*"/>
            <colspec colname="c5" colnum="5" colwidth="1*"/>
            <colspec colname="c6" colnum="6" colwidth="1*"/>
            <colspec colname="c7" colnum="7" colwidth="1*"/>
            <colspec colname="c8" colnum="8" colwidth="1*"/>
            <thead>
              <row>
                <entry align="center" namest="c1" nameend="c6">
                  <para>document</para>
                </entry>
                <entry align="center"/>
                <entry align="center">
                  <para> </para>
                </entry>
              </row>
            </thead>
            <tbody>
              <row>
                <entry align="center">
                  <para>NAL Unit header</para>
                </entry>
                <entry align="center">
                  <para>payload size</para>
                </entry>
                <entry align="center">
                  <para>UUID</para>
                </entry>
                <entry align="center">
                  <para>reserved byte</para>
                </entry>
                <entry align="center">
                  <para>metadata TLVs</para>
                </entry>
                <entry align="center">
                  <para>list of hashes TLV</para>
                </entry>
                <entry align="center">
                  <para>signature TLV</para>
                </entry>
                <entry align="center">
                  <para>stop bit</para>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </table>
      </para>
      <section xml:id="section_l3s_njq_bwb">
        <title>The reserved byte</title>
        <para>Right after the UUID, and before the TLV data, is a reserved byte. This byte represents
          bit flags of information that cannot be put in the TLV structure.</para>
        <para>The first bit shall be set to 1 if this is a certificate SEI; See
          <xref linkend="section_m3s_njq_bwb"/>.</para>
        <para>The second bit shall be set to 1 if emulation prevention was applied
          <emphasis role="bold">before</emphasis> this SEI (the document) was hashed for signing.
        </para>
        <para>The last bit shall be set to 0. If, in the future, 7 bits is not enough to signal
          settings outside the TLV structure, this bit will be used to signal more reserved
          bytes.</para>
      </section>
      <section xml:id="section_n3s_njq_bwb">
        <title>TLV tags</title>
        <para>Following is a list of possible TLV tags that can be part of a SEI payload. The length
          field of some of these tags can be represented with only one byte, but for ease of use all
          tags use 2 bytes for representing the length.</para>
        <para>
          <table frame="all">
            <title>TLV tags</title>
            <tgroup cols="4" align="left">
              <colspec colname="c1" colnum="1" colwidth="1.64*"/>
              <colspec colname="c2" colnum="2" colwidth="1*"/>
              <colspec colname="newCol3" colnum="3" colwidth="1*"/>
              <colspec colname="c3" colnum="4" colwidth="4.47*"/>
              <thead>
                <row>
                  <entry>
                    <para>Tag</para>
                  </entry>
                  <entry>
                    <para>#</para>
                  </entry>
                  <entry>
                    <para>Freq</para>
                  </entry>
                  <entry>
                    <para>Description</para>
                  </entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry>
                    <para>General GOP information</para>
                  </entry>
                  <entry>
                    <para>1</para>
                  </entry>
                  <entry>
                    <para>Every document</para>
                  </entry>
                  <entry>
                    <para>General information like GOP number</para>
                  </entry>
                </row>
                <row>
                  <entry>
                    <para>Hash list</para>
                  </entry>
                  <entry>
                    <para>2</para>
                  </entry>
                  <entry>
                    <para>Every document</para>
                  </entry>
                  <entry>
                    <para>List of NAL Unit hashes</para>
                  </entry>
                </row>
                <row>
                  <entry>
                    <para>Signature</para>
                  </entry>
                  <entry>
                    <para>3</para>
                  </entry>
                  <entry>
                    <para>Every document</para>
                  </entry>
                  <entry>
                    <para>The signature of the document</para>
                  </entry>
                </row>
                <row>
                  <entry>
                    <para>Cryptographic information</para>
                  </entry>
                  <entry>
                    <para>4</para>
                  </entry>
                  <entry>
                    <para>Once or every document</para>
                  </entry>
                  <entry>
                    <para>Cryptographic information such as hashing and signing algorithms</para>
                  </entry>
                </row>
                <row>
                  <entry>
                    <para>ONVIF vendor information</para>
                  </entry>
                  <entry>
                    <para>5</para>
                  </entry>
                  <entry>
                    <para>Once or at any arbitrary cadence</para>
                  </entry>
                  <entry>
                    <para>Information about the device and vendor</para>
                  </entry>
                </row>
                <row>
                  <entry>
                    <para>Certificate chain</para>
                  </entry>
                  <entry>
                    <para>6</para>
                  </entry>
                  <entry>
                    <para>Once or at any arbitrary cadence</para>
                  </entry>
                  <entry>
                    <para>The device video signing key certificate chain.</para>
                    <para>The leaf certificate includes the Public key necessary to verify
                      signatures.</para>
                  </entry>
                </row>
                <row>
                  <entry>
                    <para>Arbitrary data</para>
                  </entry>
                  <entry>
                    <para>7</para>
                  </entry>
                  <entry>
                    <para>Optional</para>
                  </entry>
                  <entry>Additional data can be put here as a vendor specific blob.</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
        </para>
      </section>
      <section xml:id="section_o3s_njq_bwb">
        <title>General GOP information</title>
        <para>This TLV shall be present in all SEIs except the Certificate SEI. It includes
          GOP specific information like a GOP counter, timestamps representing the signed period
          and the (partial) GOP-hash.</para>
        <itemizedlist>
          <listitem>
            <para>Tag version (1 byte)</para>
            <para>Version = 2</para>
          </listitem>
          <listitem>
            <para>Specification version (3 byte)</para>
            <para>The major and minor bytes shall be set to the specification revision, e.g., [25, 12].</para>
            <para>The patch byte is reserved by the open-source reference implementation code
              (github.com/onvif/media-signing-framework). Shall be set to 0 if not using
              media-signing-framework.</para>
          </listitem>
          <listitem>
            <para>Signing triggered by partial-GOP (1 byte)</para>
            <para>This byte shall be set to 1 if signing was triggered by a partial GOP, that is,
              before the end of the GOP was reached. All other SEIs have this byte set to 0. For
              example, if a very long GOP is split into three signing periods, the first two SEIs
              shall have this byte set to 1 and the last SEI shall have this byte set to 0.</para>
          </listitem>
          <listitem>
            <para>The UTC (8 bytes) based time represented by the number of 100-nanosecond intervals
              since January 1, 1601 of the frame leading the (partial) GOP.</para>
            <para>The start timestamp value is a 64 bit parameter and the 8 bytes shall be written with
              little endian.</para>
          </listitem>
          <listitem>
            <para>Only present from tag version 2.</para>
            <para>The UTC (8 bytes) based time represented by the number of 100-nanosecond intervals
              since January 1, 1601 of the frame leading the upcoming (partial) GOP.</para>
            <para>The end timestamp value is a 64 bit parameter and the 8 bytes shall be written with
              little endian.</para>
            <para>The duration of the signed (partial) GOP can now be calculated as duration =
              "end timestamp" - "start timestamp". Note that the end timestamp is exclusive.</para>
          </listitem>
          <listitem>
            <para>Partial GOP counter (4 bytes)</para>
            <para>A running counter that shall increment by 1 for each partial GOP. This counter
              is a helper during validation when detecting lost SEIs and syncing SEIs with the
              associated GOP.</para>
            <para>The counter value is a 32 bit parameter and the 4 bytes shall be written with
              little endian.</para>
          </listitem>
          <listitem>
            <para>Number of NAL Units represented by the partial-GOP hash (2 bytes)</para>
            <para>The GOP-hash added below is by definition a hash of NAL Unit hashes. For simplified
              validation knowledge of the number of NAL Units used shall be added, represented by
              an unsigned 16 bit value.</para>
          </listitem>
          <listitem>
            <para>(Partial) GOP hash  (<code>gophash</code>) (h bytes)</para>
            <para>The hash of the list of NAL Unit hashes. This hash is used to verify the entire
              GOP in one operation. Upon failure, the list of hashes, if present, is used to detect
              missing NAL Units. Number of bytes depends on the hash function used.</para>
          </listitem>
          <listitem>
            <para>Hash of the first hashable NAL Unit in the previous (partial) GOP (h bytes)</para>
            <para>In most cases this is the hash of the linked I-frame, that is, the I-frame leading
              the previously signed GOP (<code>h_anch_previous</code>). Number of bytes depends on
              the hash function used.</para>
            <para>For the first signed GOP these <code>h</code> bytes shall be set to
                <code>0x00</code>.</para>
          </listitem>
        </itemizedlist>
        <para>It is not necessary to specify <code>h</code> in this tag. The validation side can
          compute h since the total tag length is known. <code>h = (length - 27) / 2</code></para>
      </section>
      <section xml:id="section_p3s_njq_bwb">
        <title>Cryptographic information</title>
        <para>This TLV shall be present in every SEI, or in the certificate SEI if used. The
          field contains necessary information to perform cryptographic operations such as
          hashing and signing.
        </para>
        <itemizedlist>
          <listitem>
            <para>Tag version (1 byte)</para>
            <para>Version = 1</para>
          </listitem>
          <listitem>
            <para>The size of the serialized OID of the hash algorithm (1 byte)</para>
          </listitem>
          <listitem>
            <para>The OID, in serialized format of the hash algorithm used to hash NAL Units
              (variable byte)</para>
          </listitem>
          <listitem>
            <para>The size of the serialized OID of the signing algorithm (1 byte)</para>
          </listitem>
          <listitem>
            <para>Signing algorithm defined by its OID and specified here in its serialized
              form (variable byte)</para>
            <para>Not needed for EC and can therefore be excluded, hence the size can be
              set to zero.</para>
          </listitem>
          <listitem>
            <para>The cryptographic size of RSA (2 bytes)</para>
            <para>Set to zero if RSA is not used</para>
          </listitem>
        </itemizedlist>
        <para>Note that it is not necessary for the device to support all alternatives. The device
          makes the decision which combination to use.</para>
      </section>
      <section xml:id="section_r3s_njq_bwb">
        <title>ONVIF vendor info</title>
        <para>Includes information that identifies the product and vendor. These fields complement
          provenance data present in the certificate. The following fields are supported.</para>
        <itemizedlist>
          <listitem>
            <para>Tag version (1 byte)</para>
            <para>Version = 1</para>
          </listitem>
          <listitem>
            <para>Size of FW version (1 byte)</para>
            <para>The size of the FW version as a character string, excluding termination character.
              If no FW version is written, set size to 0.</para>
          </listitem>
          <listitem>
            <para>Firmware version</para>
          </listitem>
          <listitem>
            <para>Size of Serial Number (1 byte)</para>
            <para>The size of the Serial Number as a character string, excluding termination
              character. If no Serial Number is written, set size to 0.</para>
          </listitem>
          <listitem>
            <para>Serial Number or similar</para>
          </listitem>
          <listitem>
            <para>Size of Manufacturer (1 byte)</para>
            <para>The size of the Manufacturer as a character string, excluding termination
              character. If no Manufacturer is written, set size to 0.</para>
          </listitem>
          <listitem>
            <para>Manufacturer (who is the signer). It should be possible to, from this
              content, know where to get the CA certificate needed to verify the
              certificates.</para>
          </listitem>
        </itemizedlist>
      </section>
      <section xml:id="section_s3s_njq_bwb">
        <title>Hash list</title>
        <para>This optional TLV contains the hash list, for a complete GOP; I- through P- and B-frames.
        </para>
        <para>The presence of this TLV is controlled by the Low Bitrate Mode; See Section
          <xref linkend="section_low_bitrate_mode"/>.</para>
        <itemizedlist>
          <listitem>
            <para>Tag version (1 byte)</para>
            <para>Version = 1</para>
          </listitem>
          <listitem>
            <para>All hashes aligned byte by byte (N*H bytes)</para>
          </listitem>
        </itemizedlist>
      </section>
      <section xml:id="section_t3s_njq_bwb">
        <title>Signature</title>
        <para>This TLV contains the signature of the document and shall be present in
          every signed SEI.</para>
        <itemizedlist>
          <listitem>
            <para>Tag version (1 byte)</para>
            <para>Version = 1</para>
          </listitem>
          <listitem>
            <para>Actual size of signature (2 bytes)</para>
            <para>This is the written size, since not all signing algorithms generate a fixed size.
            </para>
          </listitem>
          <listitem>
            <para>The signature (max signature size bytes)</para>
            <para>A fixed size is reserved to be able to determine the payload size of the SEI. This
              makes the total size of the TLV tag fixed, hence known in advance. A known size is
              necessary to write the SEI payload size in advance and then hash the SEI and generate
              the message digest for signing.</para>
          </listitem>
        </itemizedlist>
      </section>
      <section xml:id="section_v3s_njq_bwb">
        <title>Certificate chain</title>
        <para>This TLV contains a certificate chain necessary to verify a public key.</para>
        <para>The leaf certificate includes the Public key, and upon successful verification can
          safely be extracted to use when verifying a signature.</para>
        <para>Note that a certificate chain shall not include its CA certificate.</para>
        <para>Note that this TLV shall be present in the certificate SEI. If no certificate SEI
          is added at stream start, this TLV is recommended to be present in every signed SEI,
          or at a reasonable cadance.</para>
        <para>Note that this tag may occur up to two times with certificates for both
          manufacuturer provisioning and user provisioning.</para>
        <itemizedlist>
          <listitem>
            <para>Tag version (1 byte)</para>
            <para>Version = 1</para>
          </listitem>
          <listitem>
            <para>User provisioned key (1 byte)</para>
            <para>Set this byte to 0x01 if the certificate chain in this TLV is a user provisioned
              certificate chain.</para>
          </listitem>
          <listitem>
            <para>The certificate chain in PEM format (variable bytes)</para>
          </listitem>
        </itemizedlist>
      </section>
      <section xml:id="section_u3s_njq_bwb">
        <title>Arbitrary data</title>
        <para>This optional field contains Abritrary data that the device vendor want to be
          included. There is no guarantee that the data is reasonable or readable by
          anyone not previously knowledgeable in the area.</para>
        <para xml:id="para_dv5_1gm_4xb">The data tag can be added to any SEI described in
          this specification or to a SEI of its own.</para>
        <para>This tag can be useful to add vendor or device specific information and get it
          signed.</para>
      </section>
    </section>
    <section xml:id="section_low_bitrate_mode">
      <title>Low Bitrate Mode</title>
      <para>As mentioned in the Limitation Section <xref linkend="section_g3s_njq_bwb"/> above,
        the SEI frames can become large due to the hash list. To lower the bitrate overhead,
        the device has the option to skip the Hash list tag; See Section
        <xref linkend="section_s3s_njq_bwb"/>. Skipping the Hash list tag is referred to as
        the Low Bitrate Mode.</para>
      <para>The Low Bitrate Mode affects the authentication. It is no longer possible to
        identify individual invalid and/or missing frames, since individual hashes are not
        transmitted. Instead, validation is based on the (partial) GOP hash present in the
        general GOP information tag; See Section <xref linkend="section_o3s_njq_bwb"/>. For a
        correctly verified (partial) GOP hash, all NAL Units have to be present and
        correct.</para>
    </section>
    <section xml:id="section_m3s_njq_bwb">
      <title>Certificate SEI</title>
      <para>Large data blobs like certificates contribute significantly to the increased bitrate.
        To lower the bitrate, this "only need once" information can be put in a separate
        <emphasis role="bold">certificate SEI</emphasis>, with the corresponding bit in the
        reserved byte set to 1, and signed. This self-signed SEI separates, by design, the
        certificate SEI from the video stream and can be copied and added to any exported
        material.</para>
      <para>This certificate SEI shall include the Cryptographic Information tag and the
        Certificate Chain tag with manufacturer provisioned certificates. It is further
        recommended to add the ONVIF Vendor Information to the certificate SEI as well.</para>
      <para>If the video is signed with a user provisioned signing key a second Certificate
        Chain tag shall be added to this certificate SEI, including the user provisioned
        certificates.</para>
      <para>The certificate SEI shall always be signed with the manufacturer provisioned
        signing key.</para>
      <section xml:id="section_w3s_njq_bwb">
        <title>How to generate a certificate SEI</title>
        <itemizedlist>
          <listitem>
            <para>Write SEI NAL Unit header</para>
            <para>H.264: <code>0x06 0x05</code></para>
            <para>H.265: <code>0x4e 0x01 0x05</code></para>
          </listitem>
          <listitem>
            <para>Determine the total payload size, excluding potential emulation prevention bytes.
              The total payload includes the UUID (16 bytes) and all TLV data. The final stop-bit byte
              is excluded from the payload size.</para>
          </listitem>
          <listitem>
            <para>Write the payload size according to the codec standard.</para>
            <para><literallayout><code>while (payload_size >= 0xff) {
      *nal_ptr++ = 0xff;
      payload_size -= 0xff;
  }
  *nal_ptr++ = payload_size;</code></literallayout></para>
          </listitem>
          <listitem>
            <para>Write the UUID</para>
            <para><code>0x00 0x5b 0xc9 0x3f 0x2d 0x71 0x5e 0x95 0xad 0xa4 0x79 0x6f 0x90 0x87 0x7a
                0x6f</code></para>
          </listitem>
          <listitem>
            <para>Write the reserved byte with the certificate SEI flag set; <code>0x80</code>.</para>
            <para>If emulation prevention will be applied before hashing the SEI for signing, also
              set the emulation prevention bit; <code>0xc0</code>.</para>
          </listitem>
          <listitem>
            <para>Write all the TLV data except the signature since it by definition cannot be
              written yet.</para>
            <para>The mandatory tags are the Cryptographic information and the Certificate chain.
            </para>
            <para>If the video will be signed with a user provisioned signing key write an additional
              TLV data for the user provisioned certificate chain.</para>
          </listitem>
          <listitem>
            <para>If the emulation prevention bit is set in the reserved byte, apply emulation
              prevention on the written data so far.</para>
          </listitem>
          <listitem>
            <para>Hash the written data from NAL Unit header to the last written TLV data. Denote this
              "document hash".</para>
          </listitem>
          <listitem>
            <para>Sign the document hash using the manufacturer provisioned Private signing key,
              stored in a trusted environment.</para>
          </listitem>
          <listitem>
            <para>Write the signature data to the Signature tag when signing has been completed.
            </para>
          </listitem>
          <listitem>
            <para>Write a stop bit byte; 0x80.</para>
          </listitem>
        </itemizedlist>
      </section>
    </section>
    <section xml:id="section_x3s_njq_bwb">
      <title>How to generate a SEI signing a GOP</title>
      <itemizedlist>
        <listitem>
          <para>Write SEI NAL Unit header</para>
          <para>H.264: <code>0x06 0x05</code></para>
          <para>H.265: <code>0x4e 0x01 0x05</code></para>
        </listitem>
        <listitem>
          <para>Determine the total payload size, excluding emulation prevention bytes. The total
            payload includes the UUID (16 bytes) and all TLV data.</para>
        </listitem>
        <listitem>
          <para>Write the payload size according to the codec standard.</para>
          <para><literallayout><code>while (payload_size >= 0xff) {
    *nal_ptr++ = 0xff;
    payload_size -= 0xff;
}
*nal_ptr++ = payload_size;</code></literallayout></para>
        </listitem>
        <listitem>
          <para>Write the UUID</para>
          <para><code>0x00 0x5b 0xc9 0x3f 0x2d 0x71 0x5e 0x95 0xad 0xa4 0x79 0x6f 0x90 0x87 0x7a
              0x6f</code></para>
        </listitem>
        <listitem>
          <para>Write the reserved byte without the certificate SEI flag set;
            <code>0x00</code>.</para>
          <para>If emulation prevention will be applied before hashing the SEI for signing, set the
            emulation prevention bit; <code>0x40</code>.</para>
        </listitem>
        <listitem>
          <para>Write all the TLV data except the signature since it by definition cannot be
            written yet.</para>
        </listitem>
        <listitem>
          <para>If the emulation prevention bit is set in the reserved byte, apply emulation
            preventionon the written data so far.</para>
        </listitem>
        <listitem>
          <para>Hash the written data from NAL Unit header to the last written TLV data. Denote this
            "document hash"</para>
        </listitem>
        <listitem>
          <para>Sign the document hash in a secure environment using the Private signing key.</para>
        </listitem>
        <listitem>
          <para>Write the signature data to the Signature tag when signing has been completed.
          </para>
        </listitem>
        <listitem>
          <para>Write a stop bit byte; 0x80.</para>
        </listitem>
      </itemizedlist>
    </section>
    <section xml:id="section_y3s_njq_bwb">
      <title>How to add a generated SEI to a video stream in a device</title>
      <para>Without loss of generality, consider three consecutive GOPs each starting with an
        I-frame followed by 4 non-IDRs (P- or B-frames). In text format it would look like
          <code>IPPPPIPPPPIPPPP</code>. The signing information is collected in a SEI frame
        (<code>S</code>).
        The SEI should be added to the video stream such that it follows the Access Unit (AU)
        format, i.e., it has to prepend all picture NAL Units in an AU. Each I-frame will trigger a
        signing procedure and ideally the SEI is generated and available instantaneously and can
        be attached to the stream as <code>SIPPPPSIPPPPSIPPPP</code>.</para>
      <para>In practice signing in secure hardware takes time and blocking the video stream while
        waiting adds jitter to the video stream. The device therefore has the option to add it to
        the video stream later, when signing has been completed. In such a case the text-ified
        stream can look like <code>IPSPPPISPPPPIPPSPP</code>.</para>
      <para>If the device decides to add redundancy by transmitting the SEI twice the text-ified
        stream would look like <code>IPSSPPPISSPPPPIPPSSPP</code>.</para>
    </section>
    <section xml:id="section_ifs_zfm_4xb">
      <title>Handling SetSynchronizationPoint</title>
      <para>If the device added a certificate SEI at stream start, the device shall transmit a
        new instance of the certificate SEI when the device recieves a SetSynchronizationPoint
        command, as specified in the media2 specification.</para>
    </section>
  </chapter>
  <appendix role="revhistory">
    <title>Revision History</title>
    <para/>
  </appendix>
  <appendix>
    <title>Client considerations (informative)</title>
    <section xml:id="section_z3s_njq_bwb">
      <title>Minimum requirements for client handling of a signed video stream</title>
      <para>Attached to an AU of a signed video stream may be a certificate SEI
        including all information that is only sent once; The certificate SEI bit is set.
        This SEI shall be stored for later use. Further, when exporting a video segment to
        file, this certificate SEI should be added to the first AU of that recording.</para>
      <para>The client shall make sure that the SEIs are not removed when exporting to an
        MP4 file. For a full list of requirements; See the ExportFileFormat specification.</para>
    </section>
    <section xml:id="section_ajs_njq_bwb">
      <title>Client side validation</title>
      <para>Validation is done (partial) GOP by (partial) GOP, just like the signing side signs
        (partial) GOP by (partial) GOP. The validation has to be aborted upon any failing step
        below.
        <itemizedlist>
          <listitem>
            <para>Get the manufacturer CA certificate from an external source.</para>
          </listitem>
          <listitem>
            <para>Extract the manufacturer Certificates from the SEI.</para>
          </listitem>
          <listitem>
            <para>Verify the extracted certificates with the CA certificate.</para>
          </listitem>
          <listitem>
            <para>Extract the manufacturer Public Key from the SEI.</para>
          </listitem>
          <listitem>
            <para>Verify the signature of the SEI with the extracted Public Key.</para>
          </listitem>
          <listitem>
            <para>If a user provisioned signing key was used, get the user CA certificate from an
              external source.</para>
            <para>Extract the user provisioned Certificate from the SEI.</para>
            <para>Verify the extracted user provisioned certificates with the CA certificate.</para>
            <para>Extract the user provisioned Public Key from the SEI.</para>
            <para>Verify the signature of the SEI with the extracted user provisioned Public Key.</para>
            <para>If the SEI is a certificate SEI, instead verify the signature of the certificate SEI with
              the extracted manufacturer Public Key.</para>
          </listitem>
          <listitem>
            <para>Find the SEI associated with the GOP that is to be validated.</para>
          </listitem>
          <listitem>
            <para>Verify the signature of the SEI, following the description above.</para>
          </listitem>
          <listitem>
            <para>Hash all NAL Units of the GOP in the same way as is described for the device part
              above.</para>
          </listitem>
          <listitem>
            <para>Verify the computed GOP-hash against corresponding GOP-hash in the SEI.</para>
            <para>If successful, all NAL Units are validated as authentic.</para>
            <para>Upon failure, verify each computed hash against corresponding hash in the hash
              list if present in the SEI.</para>
          </listitem>
          <listitem>
            <para>The client shall signal AUTHENTIC if all computed hashes are verified
              successfully against the hashes in the SEI, and the order is preserved and no NAL
              Units are missing.</para>
            <para>If any missing NAL Unit is detected the client shall signal AUTHENTIC WITH
              MISSING NAL UNITS.</para>
            <para>If no SEIs are present the client shall signal NOT SIGNED.</para>
            <para>If none of the above applies the video is not authentic and the client shall
              signal NOT AUTHENTIC.</para>
          </listitem>
        </itemizedlist>
      </para>
    </section>
    <section xml:id="section_bjs_njq_bwb">
      <title>Certificate validation</title>
      <para>In order to validate the certificate, one follows the certificate chain from the leaf
        certificate to the root certificate according to the x.509 standard. Since Onvif does not
        provide a trusted certificate store the client implementor and/or the end user must install
        trusted root CA certificates in the client. Typically one also need the intermediate CA
        certificate which is also provided by the device. When verifying old video, it may happen
        that the certificates have expired as compared to the current date. However, the
        verification concerns the date that the video was created as such the date should be
        validated against the claimed recording date rather than the current date. </para>
    </section>
    <section xml:id="section_cjs_njq_bwb">
      <title>Exporting a Signed Media</title>
      <para>In order to be able to verify an exported segment of Signed Media, the client must
        include the certificate SEI added in the beginning of the media stream. This can be
        combined with the Onvif Export File Format in order to provide layered video authentication,
        the media signing covers authenticity in the media layer where as the Export File Format
        provides validity on the container level. Even if this Signed Media specification is used,
        the Onvif Export File Format is still valuable as it provides more information of the
        provenance of the video as it allows the user to tell the story of the path of the video.
        </para>
    </section>
    <section xml:id="section_djs_njq_bwb">
      <title>Dangling End</title>
      <para>One special consideration is the possbility of dangling ends, i.e., that the last part
        of the stream or exported file has no SEI frame associated with it. There can be a number of
        reasons for this happening such as:</para>
      <itemizedlist>
        <listitem>
          <para>The stream was ended before the last SEI was signed and transmitted</para>
        </listitem>
        <listitem>
          <para>The file export did not include the associated SEI</para>
        </listitem>
        <listitem>
          <para>Other implementation specific issues</para>
        </listitem>
      </itemizedlist>
      <para>When exporting a recording, or trying to verify a dropped videostream, this means that
        the end of the video may not be covered by the verification information in the current
        segment. </para>
    </section>
  </appendix>
  <appendix>
    <title>Bibliography</title>
    <para> Alliance for Open Media | AV1 Bitstream &amp; Decoding Process Specification </para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://aomedia.org/av1/specification/"/>&gt;</para>
    <para>IETF RFC 3447 Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications
      Version 2.1</para>
    <para role="reference">&lt;<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.ietf.org/rfc/rfc3447.txt"/>&gt;</para>
  </appendix>
</book>
