Skip to content
GitLab
Explore
Sign in
Register
Commits on Source (2)
Add EBU BISS-CA
· 177e3753
Rafaël Carré
authored
Nov 09, 2018
177e3753
Merge branch 'funman-biss'
· d7682517
Christophe Massiot
authored
Jan 14, 2019
d7682517
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
d7682517
...
...
@@ -27,6 +27,8 @@ install: bitstream.pc
@
install
-m
644 dvb/
*
.h
$(
INCLUDE
)
/dvb
@
install
-d
$(
INCLUDE
)
/dvb/si
@
install
-m
644 dvb/si/
*
.h
$(
INCLUDE
)
/dvb/si
@
install
-d
$(
INCLUDE
)
/ebu
@
install
-m
644 ebu/
*
.h
$(
INCLUDE
)
/ebu
@
install
-d
$(
INCLUDE
)
/ietf
@
install
-m
644 ietf/
*
$(
INCLUDE
)
/ietf
@
install
-d
$(
INCLUDE
)
/ieee
...
...
NEWS
View file @
d7682517
1.6 (TODO)
=================
- Add EBU BISS-CA
1.5 (6 November 2018)
=================
- Add SDES
...
...
ebu/biss.h
0 → 100644
View file @
d7682517
/*****************************************************************************
* biss.h: BISS-CA Entitlement Management Message Table (EMM)
*****************************************************************************
* Copyright (C) 2018 Open Broadcast Systems Ltd.
*
* Authors: Rafaël Carré <funman@videolan.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*****************************************************************************/
/*
* Normative references:
* - EBU Tech 3292
*/
#ifndef __BITSTREAM_EBU_BISS_H__
#define __BITSTREAM_EBU_BISS_H__
#include
<bitstream/common.h>
#include
<bitstream/mpeg/psi/psi.h>
#include
<bitstream/mpeg/psi/descriptors.h>
#ifdef __cplusplus
extern
"C"
{
#endif
/*****************************************************************************
* Conditional Access Table
*****************************************************************************/
#define BISSCA_EMM_TABLE_ID 0x81
#define BISSCA_EMM_HEADER_SIZE PSI_HEADER_SIZE_SYNTAX1
#define BISSCA_EMM_CIPHER_RSA_2048_OAEP 0
#define BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE (2048/8)
#define BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE (64/8)
static
inline
void
bissca_emm_init
(
uint8_t
*
p_emm
,
uint16_t
esid
)
{
psi_init
(
p_emm
,
true
);
psi_set_tableid
(
p_emm
,
BISSCA_EMM_TABLE_ID
);
p_emm
[
1
]
&=
~
0x40
;
psi_set_tableidext
(
p_emm
,
esid
);
psi_set_section
(
p_emm
,
0
);
psi_set_lastsection
(
p_emm
,
0
);
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
3
]
=
0x0f
;
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
4
]
=
0xf0
;
}
static
inline
void
bissca_emm_set_onid
(
uint8_t
*
p_emm
,
uint16_t
onid
)
{
p_emm
[
BISSCA_EMM_HEADER_SIZE
]
=
onid
>>
8
;
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
1
]
=
onid
&
0xff
;
}
static
inline
uint16_t
bissca_emm_get_onid
(
const
uint8_t
*
p_emm
)
{
return
(
p_emm
[
BISSCA_EMM_HEADER_SIZE
]
<<
8
)
|
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
1
];
}
static
inline
void
bissca_emm_set_last_table_id
(
uint8_t
*
p_emm
,
uint8_t
last_table_id
)
{
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
2
]
=
last_table_id
;
}
static
inline
uint8_t
bissca_emm_get_last_table_id
(
const
uint8_t
*
p_emm
)
{
return
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
2
];
}
static
inline
void
bissca_emm_set_emm_cipher_type
(
uint8_t
*
p_emm
,
uint8_t
bissca_emm_cipher_type
)
{
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
3
]
&=
0x0f
;
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
3
]
|=
(
emm_cipher_type
<<
5
);
}
static
inline
uint8_t
bissca_emm_get_emm_cipher_type
(
const
uint8_t
*
p_emm
)
{
return
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
3
]
>>
5
;
}
static
inline
void
bissca_emm_set_entitlement_priv_data_loop
(
uint8_t
*
p_emm
,
bool
entitlement_priv_data_loop
)
{
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
3
]
&=
0x0f
;
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
3
]
|=
(
!!
entitlement_priv_data_loop
<<
4
);
}
static
inline
bool
bissca_emm_get_entitlement_priv_data_loop
(
const
uint8_t
*
p_emm
)
{
return
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
3
]
&
0x10
;
}
static
inline
void
bissca_emm_set_length
(
uint8_t
*
p_emm
,
uint16_t
i_emm_length
)
{
// TODO: take N of loops ?
psi_set_length
(
p_emm
,
BISSCA_EMM_HEADER_SIZE
+
6
+
PSI_CRC_SIZE
-
PSI_HEADER_SIZE
+
i_emm_length
);
}
static
inline
uint16_t
bissca_emm_get_desclength
(
const
uint8_t
*
p_emm
)
{
return
((
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
4
]
&
0xf
)
<<
8
)
|
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
5
];
}
static
inline
void
bissca_emm_set_desclength
(
uint8_t
*
p_emm
,
uint16_t
i_desc_len
)
{
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
4
]
&=
0xf0
;
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
4
]
|=
(
i_desc_len
<<
8
)
&
0xf
;
p_emm
[
BISSCA_EMM_HEADER_SIZE
+
5
]
=
i_desc_len
&
0xff
;
}
static
inline
uint8_t
*
bissca_emm_get_descl
(
uint8_t
*
p_emm
)
{
return
p_emm
+
BISSCA_EMM_HEADER_SIZE
+
6
;
}
static
inline
const
uint8_t
*
bissca_emm_get_descl_const
(
const
uint8_t
*
p_emm
)
{
return
p_emm
+
BISSCA_EMM_HEADER_SIZE
+
6
;
}
static
inline
uint8_t
*
bissca_emm_get_emmn
(
uint8_t
*
p_emm
,
int
n
)
{
uint16_t
i_section_size
=
psi_get_length
(
p_emm
)
+
PSI_HEADER_SIZE
-
PSI_CRC_SIZE
;
uint8_t
*
p_emm_n
=
p_emm
+
BISSCA_EMM_HEADER_SIZE
+
6
+
bissca_emm_get_desclength
(
p_emm
);
if
(
p_emm_n
-
p_emm
>
i_section_size
)
return
NULL
;
bool
priv
=
bissca_emm_get_entitlement_priv_data_loop
(
p_emm
);
while
(
n
)
{
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
;
p_emm_n
+=
BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE
+
BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE
;
if
(
priv
)
{
if
(
p_emm_n
+
DESCS_HEADER_SIZE
-
p_emm
>
i_section_size
)
return
NULL
;
uint16_t
desc_len
=
descs_get_length
(
p_emm_n
);
if
(
p_emm_n
+
DESCS_HEADER_SIZE
+
desc_len
-
p_emm
>
i_section_size
)
return
NULL
;
p_emm_n
+=
DESCS_HEADER_SIZE
+
desc_len
;
}
n
--
;
}
if
(
p_emm_n
-
p_emm
>=
i_section_size
)
return
NULL
;
return
p_emm_n
;
}
static
inline
void
bissca_emmn_get_ekid
(
uint8_t
*
p_emm_n
,
uint8_t
ekid
[
BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE
])
{
memcpy
(
ekid
,
p_emm_n
,
BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE
);
}
static
inline
void
bissca_emmn_set_ekid
(
uint8_t
*
p_emm_n
,
const
uint8_t
ekid
[
BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE
])
{
memcpy
(
p_emm_n
,
ekid
,
BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE
);
}
static
inline
void
bissca_emmn_get_esd
(
uint8_t
*
p_emm_n
,
uint8_t
esd
[
BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE
])
{
memcpy
(
esd
,
&
p_emm_n
[
BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE
],
BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE
);
}
static
inline
void
bissca_emmn_set_esd
(
uint8_t
*
p_emm_n
,
const
uint8_t
esd
[
BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE
])
{
memcpy
(
&
p_emm_n
[
BISSCA_EMM_RSA_2048_OAEP_EKID_SIZE
],
esd
,
BISSCA_EMM_RSA_2048_OAEP_ESD_SIZE
);
}
static
inline
bool
bissca_emm_validate
(
const
uint8_t
*
p_emm
)
{
uint16_t
i_section_size
=
psi_get_length
(
p_emm
)
+
PSI_HEADER_SIZE
-
PSI_CRC_SIZE
;
if
(
!
psi_get_syntax
(
p_emm
)
||
psi_get_section
(
p_emm
)
||
psi_get_lastsection
(
p_emm
)
||
psi_get_tableid
(
p_emm
)
!=
BISSCA_EMM_TABLE_ID
)
return
false
;
if
(
i_section_size
<
BISSCA_EMM_HEADER_SIZE
+
6
||
i_section_size
<
BISSCA_EMM_HEADER_SIZE
+
6
+
bissca_emm_get_desclength
(
p_emm
))
return
false
;
if
(
!
descl_validate
(
emm_get_descl_const
(
p_emm
),
bissca_emm_get_desclength
(
p_emm
)))
return
false
;
// TODO: validate RSA loop ?
return
true
;
}
static
inline
bool
bissca_emm_table_validate
(
uint8_t
**
pp_sections
)
{
uint8_t
i_last_section
=
psi_table_get_lastsection
(
pp_sections
);
uint8_t
i
;
for
(
i
=
0
;
i
<=
i_last_section
;
i
++
)
{
uint8_t
*
p_section
=
psi_table_get_section
(
pp_sections
,
i
);
if
(
!
psi_check_crc
(
p_section
))
return
false
;
}
return
true
;
}
#ifdef __cplusplus
}
#endif
#endif