<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr">On Mon, 14 Jan 2019 at 21:10, Christophe Massiot <<a href="mailto:gitlab@videolan.org">gitlab@videolan.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Christophe Massiot pushed to branch master at VideoLAN / bitstream<br>
<br>
<br>
Commits:<br>
177e3753 by Rafaël Carré at 2018-12-03T16:38:38Z<br>
Add EBU BISS-CA<br>
<br>
- - - - -<br>
d7682517 by Christophe Massiot at 2019-01-14T21:09:53Z<br>
Merge branch &#39;funman-biss&#39;<br>
<br>
- - - - -<br>
<br>
<br>
3 changed files:<br>
<br>
- Makefile<br>
- NEWS<br>
- + ebu/biss.h<br>
<br>
<br>
Changes:<br>
<br>
=====================================<br>
Makefile<br>
=====================================<br>
@@ -27,6 +27,8 @@ install: bitstream.pc<br>
        @install -m 644 dvb/*.h $(INCLUDE)/dvb<br>
        @install -d $(INCLUDE)/dvb/si<br>
        @install -m 644 dvb/si/*.h $(INCLUDE)/dvb/si<br>
+       @install -d $(INCLUDE)/ebu<br>
+       @install -m 644 ebu/*.h $(INCLUDE)/ebu<br>
        @install -d $(INCLUDE)/ietf<br>
        @install -m 644 ietf/* $(INCLUDE)/ietf<br>
        @install -d $(INCLUDE)/ieee<br>
<br>
<br>
=====================================<br>
NEWS<br>
=====================================<br>
@@ -1,3 +1,7 @@<br>
+1.6 (TODO)<br>
+=================<br>
+ - Add EBU BISS-CA<br>
+<br>
 1.5 (6 November 2018)<br>
 =================<br>
  - Add SDES<br>
<br>
<br>
=====================================<br>
ebu/biss.h<br>
=====================================<br>
@@ -0,0 +1,225 @@<br>
+/*****************************************************************************<br>
+ * biss.h: BISS-CA Entitlement Management Message Table (EMM)<br>
+ *****************************************************************************<br>
+ * Copyright (C) 2018 Open Broadcast Systems Ltd.<br>
+ *<br>
+ * Authors: Rafaël Carré <<a href="mailto:funman@videolan.org" target="_blank">funman@videolan.org</a>><br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining<br>
+ * a copy of this software and associated documentation files (the<br>
+ * "Software"), to deal in the Software without restriction, including<br>
+ * without limitation the rights to use, copy, modify, merge, publish,<br>
+ * distribute, sublicense, and/or sell copies of the Software, and to<br>
+ * permit persons to whom the Software is furnished to do so, subject<br>
+ * to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice shall be<br>
+ * included in all copies or substantial portions of the Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,<br>
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF<br>
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.<br>
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY<br>
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,<br>
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE<br>
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<br>
+ *****************************************************************************/<br>
+<br>
+/*<br>
+ * Normative references:<br>
+ *  - EBU Tech 3292<br>
+ */<br>
+<br>
+#ifndef __BITSTREAM_EBU_BISS_H__<br>
+#define __BITSTREAM_EBU_BISS_H__<br>
+<br>
+#include <bitstream/common.h><br>
+#include <bitstream/mpeg/psi/psi.h><br>
+#include <bitstream/mpeg/psi/descriptors.h><br>
+<br>
+#ifdef __cplusplus<br>
+extern "C"<br>
+{<br>
+#endif<br>
+<br>
+/*****************************************************************************<br>
+ * Conditional Access Table<br>
+ *****************************************************************************/<br>
+#define BISSCA_EMM_TABLE_ID            0x81<br>
+#define BISSCA_EMM_HEADER_SIZE         PSI_HEADER_SIZE_SYNTAX1<br>
+<br>
+#define BISSCA_EMM_CIPHER_RSA_2048_OAEP    0<br>
+#define BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE  (2048/8)<br>
+#define BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE  (64/8)<br>
+<br>
+static inline void bissca_emm_init(uint8_t *p_emm, uint16_t esid)<br>
+{<br>
+    psi_init(p_emm, true);<br>
+    psi_set_tableid(p_emm, BISSCA_EMM_TABLE_ID);<br>
+    p_emm[1] &= ~0x40;<br>
+    psi_set_tableidext(p_emm, esid);<br>
+    psi_set_section(p_emm, 0);<br>
+    psi_set_lastsection(p_emm, 0);<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE+3] = 0x0f;<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE+4] = 0xf0;<br>
+}<br>
+<br>
+static inline void bissca_emm_set_onid(uint8_t *p_emm, uint16_t onid)<br>
+{<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE] = onid >> 8;<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE+1] = onid & 0xff;<br>
+}<br>
+<br>
+static inline uint16_t bissca_emm_get_onid(const uint8_t *p_emm)<br>
+{<br>
+    return (p_emm[BISSCA_EMM_HEADER_SIZE] << 8) |<br>
+        p_emm[BISSCA_EMM_HEADER_SIZE+1];<br>
+}<br>
+<br>
+static inline void bissca_emm_set_last_table_id(uint8_t *p_emm, uint8_t last_table_id)<br>
+{<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE+2] = last_table_id;<br>
+}<br>
+<br>
+static inline uint8_t bissca_emm_get_last_table_id(const uint8_t *p_emm)<br>
+{<br>
+    return p_emm[BISSCA_EMM_HEADER_SIZE+2];<br>
+}<br>
+<br>
+static inline void bissca_emm_set_emm_cipher_type(uint8_t *p_emm, uint8_t bissca_emm_cipher_type)<br>
+{<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE+3] &= 0x0f;<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE+3] |= (emm_cipher_type << 5);<br>
+}<br>
+<br>
+static inline uint8_t bissca_emm_get_emm_cipher_type(const uint8_t *p_emm)<br>
+{<br>
+    return p_emm[BISSCA_EMM_HEADER_SIZE+3] >> 5;<br>
+}<br>
+<br>
+static inline void bissca_emm_set_entitlement_priv_data_loop(uint8_t *p_emm, bool entitlement_priv_data_loop)<br>
+{<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE+3] &= 0x0f;<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE+3] |= (!!entitlement_priv_data_loop << 4);<br>
+}<br>
+<br>
+static inline bool bissca_emm_get_entitlement_priv_data_loop(const uint8_t *p_emm)<br>
+{<br>
+    return p_emm[BISSCA_EMM_HEADER_SIZE+3] & 0x10;<br>
+}<br>
+<br>
+static inline void bissca_emm_set_length(uint8_t *p_emm, uint16_t i_emm_length)<br>
+{<br>
+    // TODO: take N of loops ?<br>
+    psi_set_length(p_emm, BISSCA_EMM_HEADER_SIZE + 6 + PSI_CRC_SIZE - PSI_HEADER_SIZE<br>
+                    + i_emm_length);<br>
+}<br>
+<br>
+static inline uint16_t bissca_emm_get_desclength(const uint8_t *p_emm)<br>
+{<br>
+    return ((p_emm[BISSCA_EMM_HEADER_SIZE + 4] & 0xf) << 8) |<br>
+        p_emm[BISSCA_EMM_HEADER_SIZE + 5];<br>
+}<br>
+<br>
+static inline void bissca_emm_set_desclength(uint8_t *p_emm, uint16_t i_desc_len)<br>
+{<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE + 4] &= 0xf0;<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE + 4] |= (i_desc_len << 8) & 0xf;<br>
+    p_emm[BISSCA_EMM_HEADER_SIZE + 5] = i_desc_len & 0xff;<br>
+}<br>
+<br>
+static inline uint8_t *bissca_emm_get_descl(uint8_t *p_emm)<br>
+{<br>
+    return p_emm + BISSCA_EMM_HEADER_SIZE + 6;<br>
+}<br>
+<br>
+static inline const uint8_t *bissca_emm_get_descl_const(const uint8_t *p_emm)<br>
+{<br>
+    return p_emm + BISSCA_EMM_HEADER_SIZE + 6;<br>
+}<br>
+<br>
+static inline uint8_t *bissca_emm_get_emmn(uint8_t *p_emm, int n)<br>
+{<br>
+    uint16_t i_section_size = psi_get_length(p_emm) + PSI_HEADER_SIZE<br>
+                               - PSI_CRC_SIZE;<br>
+    uint8_t *p_emm_n = p_emm + BISSCA_EMM_HEADER_SIZE + 6 + bissca_emm_get_desclength(p_emm);<br>
+    if (p_emm_n - p_emm > i_section_size) return NULL;<br>
+    bool priv = bissca_emm_get_entitlement_priv_data_loop(p_emm);<br>
+<br>
+    while (n) {<br>
+        if (p_emm_n + BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE + BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE - p_emm > i_section_size) return NULL;<br>
+        p_emm_n += BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE + BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE;<br>
+        if (priv) {<br>
+            if (p_emm_n + DESCS_HEADER_SIZE - p_emm > i_section_size) return NULL;<br>
+            uint16_t desc_len = descs_get_length(p_emm_n);<br>
+            if (p_emm_n + DESCS_HEADER_SIZE + desc_len - p_emm > i_section_size) return NULL;<br>
+            p_emm_n += DESCS_HEADER_SIZE + desc_len;<br>
+        }<br>
+        n--;<br>
+    }<br>
+    if (p_emm_n - p_emm >= i_section_size) return NULL;<br>
+    return p_emm_n;<br>
+}<br>
+<br>
+static inline void bissca_emmn_get_ekid(uint8_t *p_emm_n, uint8_t ekid[BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE])<br>
+{<br>
+    memcpy(ekid, p_emm_n, BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE);<br>
+}<br>
+<br>
+static inline void bissca_emmn_set_ekid(uint8_t *p_emm_n, const uint8_t ekid[BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE])<br>
+{<br>
+    memcpy(p_emm_n, ekid, BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE);<br>
+}<br>
+<br>
+static inline void bissca_emmn_get_esd(uint8_t *p_emm_n, uint8_t esd[BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE])<br>
+{<br>
+    memcpy(esd, &p_emm_n[BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE], BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE);<br>
+}<br>
+<br>
+static inline void bissca_emmn_set_esd(uint8_t *p_emm_n, const uint8_t esd[BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE])<br>
+{<br>
+    memcpy(&p_emm_n[BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE], esd, BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE);<br>
+}<br>
+<br>
+static inline bool bissca_emm_validate(const uint8_t *p_emm)<br>
+{<br>
+    uint16_t i_section_size = psi_get_length(p_emm) + PSI_HEADER_SIZE<br>
+                               - PSI_CRC_SIZE;<br>
+<br>
+    if (!psi_get_syntax(p_emm) || psi_get_section(p_emm)<br>
+         || psi_get_lastsection(p_emm)<br>
+         || psi_get_tableid(p_emm) != BISSCA_EMM_TABLE_ID)<br>
+        return false;<br>
+<br>
+    if (i_section_size < BISSCA_EMM_HEADER_SIZE + 6<br>
+         || i_section_size < BISSCA_EMM_HEADER_SIZE + 6 + bissca_emm_get_desclength(p_emm))<br>
+        return false;<br>
+<br>
+    if (!descl_validate(emm_get_descl_const(p_emm), bissca_emm_get_desclength(p_emm)))<br>
+        return false;<br>
+<br>
+    // TODO: validate RSA loop ?<br>
+<br>
+    return true;<br>
+}<br>
+<br>
+static inline bool bissca_emm_table_validate(uint8_t **pp_sections)<br>
+{<br>
+    uint8_t i_last_section = psi_table_get_lastsection(pp_sections);<br>
+    uint8_t i;<br>
+<br>
+    for (i = 0; i <= i_last_section; i++) {<br>
+        uint8_t *p_section = psi_table_get_section(pp_sections, i);<br>
+<br>
+        if (!psi_check_crc(p_section))<br>
+            return false;<br>
+    }<br>
+<br>
+    return true;<br>
+}<br>
+<br>
+#ifdef __cplusplus<br>
+}<br>
+#endif<br>
+<br>
+#endif<br>
<br>
<br>
<br>
View it on GitLab: <a href="https://code.videolan.org/videolan/bitstream/compare/4de132a7ef4ba3120b776d20c3941da5a07c5100...d7682517d136e4c19a4b4dc7d2d3fad1e668e2b6" rel="noreferrer" target="_blank">https://code.videolan.org/videolan/bitstream/compare/4de132a7ef4ba3120b776d20c3941da5a07c5100...d7682517d136e4c19a4b4dc7d2d3fad1e668e2b6</a><br>
<br>
-- <br>
View it on GitLab: <a href="https://code.videolan.org/videolan/bitstream/compare/4de132a7ef4ba3120b776d20c3941da5a07c5100...d7682517d136e4c19a4b4dc7d2d3fad1e668e2b6" rel="noreferrer" target="_blank">https://code.videolan.org/videolan/bitstream/compare/4de132a7ef4ba3120b776d20c3941da5a07c5100...d7682517d136e4c19a4b4dc7d2d3fad1e668e2b6</a><br>
You're receiving this email because of your account on <a href="http://code.videolan.org" rel="noreferrer" target="_blank">code.videolan.org</a>.<br>
_______________________________________________<br>
biTStream-devel mailing list<br>
<a href="mailto:biTStream-devel@videolan.org" target="_blank">biTStream-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/bitstream-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/bitstream-devel</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature">Callum Urquhart</div></div>