Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joshua Root
libaacs
Commits
ca48204a
Commit
ca48204a
authored
Jan 13, 2016
by
npzacs
Browse files
Add basic CCI parsing
parent
72e4a984
Changes
6
Hide whitespace changes
Inline
Side-by-side
Makefile.am
View file @
ca48204a
...
...
@@ -12,6 +12,9 @@ lib_LTLIBRARIES = libaacs.la
libaacs_la_SOURCES
=
\
src/libaacs/aacs.h
\
src/libaacs/aacs.c
\
src/libaacs/cci_data.h
\
src/libaacs/cci.h
\
src/libaacs/cci.c
\
src/libaacs/content_cert.h
\
src/libaacs/content_cert.c
\
src/libaacs/crypto.h
\
...
...
src/libaacs/aacs.c
View file @
ca48204a
...
...
@@ -26,6 +26,8 @@
#include "aacs-version.h"
#include "aacs.h"
#include "cci.h"
#include "cci_data.h"
#include "content_cert.h"
#include "crypto.h"
#include "mmc.h"
...
...
@@ -772,6 +774,58 @@ static void _find_config_entry(AACS *aacs, title_entry_list *ce,
}
}
static
size_t
_read_cci_file
(
AACS
*
aacs
,
int
cps_unit
,
void
**
data
)
{
char
*
fname
;
size_t
size
=
0
;
fname
=
str_printf
(
"AACS"
DIR_SEP
"CPSUnit%05d.cci"
,
cps_unit
);
if
(
fname
)
{
size
=
_read_file
(
aacs
,
fname
,
data
);
X_FREE
(
fname
);
if
(
size
>=
2048
)
{
return
size
;
}
X_FREE
(
*
data
);
}
/* try backup copy */
fname
=
str_printf
(
"AACS"
DIR_SEP
"DUPLICATE"
DIR_SEP
"CPSUnit%05d.cci"
,
cps_unit
);
if
(
fname
)
{
size
=
_read_file
(
aacs
,
fname
,
data
);
X_FREE
(
fname
);
if
(
size
>=
2048
)
{
return
size
;
}
X_FREE
(
*
data
);
}
return
0
;
}
static
AACS_CCI
*
_read_cci
(
AACS
*
aacs
,
int
cps_unit
)
{
AACS_CCI
*
cci
;
void
*
data
;
size_t
size
;
size
=
_read_cci_file
(
aacs
,
cps_unit
,
&
data
);
if
(
!
size
)
{
BD_DEBUG
(
DBG_AACS
|
DBG_CRIT
,
"Failed to read CPS unit usage file %d
\n
"
,
cps_unit
);
return
NULL
;
}
cci
=
cci_parse
(
data
,
size
);
X_FREE
(
data
);
return
cci
;
}
static
int
_calc_uks
(
AACS
*
aacs
,
config_file
*
cf
)
{
AACS_FILE_H
*
fp
=
NULL
;
...
...
@@ -1344,6 +1398,47 @@ uint32_t aacs_get_bus_encryption(AACS *aacs)
(
aacs
->
bec
*
AACS_BUS_ENCRYPTION_CAPABLE
);
}
static
int
_cps_unit
(
AACS
*
aacs
,
uint32_t
title
)
{
if
(
!
aacs
||
!
aacs
->
cps_units
)
{
BD_DEBUG
(
DBG_AACS
|
DBG_CRIT
,
"CPS units not read !
\n
"
);
return
-
1
;
}
if
(
title
==
0xffff
)
{
return
aacs
->
cps_units
[
0
];
}
else
if
(
title
<=
aacs
->
num_titles
)
{
return
aacs
->
cps_units
[
title
+
1
];
}
BD_DEBUG
(
DBG_AACS
|
DBG_CRIT
,
"invalid title %u
\n
"
,
title
);
return
-
1
;
}
struct
aacs_basic_cci
*
aacs_get_basic_cci
(
AACS
*
aacs
,
uint32_t
title
)
{
AACS_BASIC_CCI
*
data
=
NULL
;
int
cps_unit
;
cps_unit
=
_cps_unit
(
aacs
,
title
);
if
(
cps_unit
<
0
)
{
return
NULL
;
}
AACS_CCI
*
cci
=
_read_cci
(
aacs
,
cps_unit
);
if
(
!
cci
)
{
return
NULL
;
}
const
AACS_BASIC_CCI
*
bcci
=
cci_get_basic_cci
(
cci
);
if
(
bcci
)
{
data
=
malloc
(
sizeof
(
*
data
));
memcpy
(
data
,
bcci
,
sizeof
(
*
data
));
}
cci_free
(
&
cci
);
return
data
;
}
void
aacs_select_title
(
AACS
*
aacs
,
uint32_t
title
)
{
...
...
src/libaacs/aacs.h
View file @
ca48204a
...
...
@@ -82,4 +82,10 @@ AACS_PUBLIC void aacs_free_rl(AACS_RL_ENTRY **rl);
AACS_PUBLIC
uint32_t
aacs_get_bus_encryption
(
AACS
*
);
/* Copy Control Information */
struct
aacs_basic_cci
;
AACS_PUBLIC
struct
aacs_basic_cci
*
aacs_get_basic_cci
(
AACS
*
,
uint32_t
title
);
#endif
/* AACS_H_ */
src/libaacs/cci.c
0 → 100644
View file @
ca48204a
/*
* This file is part of libaacs
* Copyright (C) 2016 npzacs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "cci.h"
#include "cci_data.h"
#include "util/logging.h"
#include "util/macro.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define DBG_CCI DBG_AACS
/* CCI type */
enum
{
cci_AACS_BASIC_CCI
=
0x0101
,
cci_AACS_ENHANCED_TITLE_USAGE
=
0x0111
,
};
typedef
struct
{
uint16_t
type
;
uint16_t
version
;
uint16_t
data_length
;
union
{
AACS_BASIC_CCI
basic_cci
;
}
u
;
}
AACS_CCI_ENTRY
;
struct
aacs_cci
{
unsigned
int
num_entry
;
AACS_CCI_ENTRY
*
entry
;
};
static
void
_bitcpy
(
void
*
dst
,
const
const
void
*
src
,
size_t
num_bits
)
{
size_t
bytes
=
num_bits
>>
3
;
size_t
bits
=
num_bits
&
3
;
if
(
bytes
)
{
memcpy
(
dst
,
src
,
bytes
);
}
if
(
bits
)
{
uint8_t
mask
=
(((
1
<<
(
8
-
bits
)))
-
1
)
^
0xff
;
((
uint8_t
*
)
dst
)[
bytes
]
=
((
const
uint8_t
*
)
src
)[
bytes
]
&
mask
;
}
}
static
int
cci_parse_entry
(
AACS_CCI_ENTRY
*
e
,
const
uint8_t
*
data
,
size_t
size
)
{
memset
(
e
,
0
,
sizeof
(
AACS_CCI_ENTRY
));
if
(
size
<
6
)
{
return
-
1
;
}
e
->
type
=
MKINT_BE16
(
data
);
e
->
version
=
MKINT_BE16
(
data
+
2
);
e
->
data_length
=
MKINT_BE16
(
data
+
4
);
if
(
size
+
6
<
e
->
data_length
)
{
BD_DEBUG
(
DBG_CCI
,
"CCI: not enough data (type 0x%04x)
\n
"
,
e
->
type
);
return
-
1
;
}
switch
(
e
->
type
)
{
case
cci_AACS_BASIC_CCI
:
if
(
e
->
data_length
==
0x84
)
{
BD_DEBUG
(
DBG_CCI
,
"CCI: AACS basic CCI found
\n
"
);
e
->
u
.
basic_cci
.
epn
=
(
data
[
6
]
&
0x04
)
>>
2
;
e
->
u
.
basic_cci
.
cci
=
data
[
6
]
&
0x03
;
e
->
u
.
basic_cci
.
image_constraint
=
(
data
[
7
]
&
0x10
)
>>
4
;
e
->
u
.
basic_cci
.
digital_only
=
(
data
[
7
]
&
0x40
)
>>
3
;
e
->
u
.
basic_cci
.
apstb
=
data
[
7
]
&
0x07
;
e
->
u
.
basic_cci
.
num_titles
=
MKINT_BE16
(
data
+
8
);
if
(
e
->
u
.
basic_cci
.
num_titles
>
1024
)
{
BD_DEBUG
(
DBG_CCI
,
"CCI: title type map too large (%u)
\n
"
,
e
->
u
.
basic_cci
.
num_titles
);
return
-
1
;
}
_bitcpy
(
e
->
u
.
basic_cci
.
title_type
,
data
+
10
,
e
->
u
.
basic_cci
.
num_titles
);
return
1
;
}
break
;
case
cci_AACS_ENHANCED_TITLE_USAGE
:
BD_DEBUG
(
DBG_CCI
,
"CCI: AACS enhanced title usage CCI found
\n
"
);
return
1
;
default:
BD_DEBUG
(
DBG_CCI
,
"CCI: AACS CCI 0x%04x found
\n
"
,
e
->
type
);
break
;
}
return
0
;
}
AACS_CCI
*
cci_parse
(
const
void
*
data
,
size_t
size
)
{
AACS_CCI
*
cci
;
const
uint8_t
*
p
=
data
;
unsigned
int
ii
;
if
(
size
<
16
)
{
return
NULL
;
}
cci
=
calloc
(
1
,
sizeof
(
*
cci
));
if
(
!
cci
)
{
return
NULL
;
}
cci
->
num_entry
=
MKINT_BE16
(
p
);
p
+=
16
;
size
-=
16
;
cci
->
entry
=
calloc
(
cci
->
num_entry
,
sizeof
(
*
(
cci
->
entry
)));
if
(
!
cci
->
entry
)
{
cci_free
(
&
cci
);
return
NULL
;
}
BD_DEBUG
(
DBG_CCI
,
"CCI: %d entries
\n
"
,
cci
->
num_entry
);
for
(
ii
=
0
;
ii
<
cci
->
num_entry
;
ii
++
)
{
AACS_CCI_ENTRY
*
e
=
&
cci
->
entry
[
ii
];
if
(
cci_parse_entry
(
e
,
p
,
size
)
<
0
)
{
BD_DEBUG
(
DBG_CCI
,
"CCI parsing failed
\n
"
);
cci_free
(
&
cci
);
return
NULL
;
}
p
+=
6
+
e
->
data_length
;
size
-=
6
+
e
->
data_length
;
}
return
cci
;
}
void
cci_free
(
AACS_CCI
**
pp
)
{
if
(
pp
&&
*
pp
)
{
X_FREE
((
*
pp
)
->
entry
);
X_FREE
(
*
pp
);
}
}
AACS_BASIC_CCI
*
cci_get_basic_cci
(
AACS_CCI
*
cci
)
{
unsigned
int
ii
;
for
(
ii
=
0
;
ii
<
cci
->
num_entry
;
ii
++
)
{
AACS_CCI_ENTRY
*
e
=
&
cci
->
entry
[
ii
];
if
(
e
->
type
==
cci_AACS_BASIC_CCI
)
{
return
&
e
->
u
.
basic_cci
;
}
}
return
NULL
;
}
src/libaacs/cci.h
0 → 100644
View file @
ca48204a
/*
* This file is part of libaacs
* Copyright (C) 2016 npzacs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef AACS_CCI_H_
#define AACS_CCI_H_
#include "util/attributes.h"
#include <stddef.h>
typedef
struct
aacs_cci
AACS_CCI
;
BD_PRIVATE
AACS_CCI
*
cci_parse
(
const
void
*
data
,
size_t
len
);
BD_PRIVATE
void
cci_free
(
AACS_CCI
**
);
BD_PRIVATE
struct
aacs_basic_cci
*
cci_get_basic_cci
(
AACS_CCI
*
cci
);
#endif
/* AACS_CCI_H_ */
src/libaacs/cci_data.h
0 → 100644
View file @
ca48204a
/*
* This file is part of libaacs
* Copyright (C) 2016 npzacs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef AACS_CCI_DATA_H_
#define AACS_CCI_DATA_H_
#include <stdint.h>
/* Blu-ray Disc Pre-recorded Book, 3.9.4.2 Basic CCI for AACS */
typedef
struct
aacs_basic_cci
{
uint8_t
epn
;
/* Encryption Plus Non-assertion. Valid if cci == 0. */
uint8_t
cci
;
/* Copy Control Information. 0 == copy freely. */
uint8_t
image_constraint
;
/* High Definition Analog Output in High Definition Analog Form */
uint8_t
digital_only
;
/* Output of decrypted content is allowed only for Digital Outputs */
uint8_t
apstb
;
/* Analog copy protection information */
uint16_t
num_titles
;
/* title types (bit mask) */
uint8_t
title_type
[
1024
/
8
];
/* Title type bit mask. 0 == basic title. 1 == enhanced title. */
}
AACS_BASIC_CCI
;
#endif
/* AACS_CCI_DATA_H_ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment