Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
Jean-Baptiste Kempf
libaacs
Commits
c9c8ad90
Commit
c9c8ad90
authored
Jun 23, 2020
by
npzacs
Committed by
hpi1
Jul 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add MKB and UK file dump tools
parent
7eab1714
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
466 additions
and
1 deletion
+466
-1
Makefile.am
Makefile.am
+16
-1
src/devtools/mkb_dump.c
src/devtools/mkb_dump.c
+260
-0
src/devtools/read_file.h
src/devtools/read_file.h
+77
-0
src/devtools/uk_dump.c
src/devtools/uk_dump.c
+113
-0
No files found.
Makefile.am
View file @
c9c8ad90
...
...
@@ -93,7 +93,7 @@ dist-hook:
# programs
#
noinst_PROGRAMS
=
parser_test
noinst_PROGRAMS
=
parser_test
uk_dump mkb_dump
bin_PROGRAMS
=
aacs_info
parser_test_SOURCES
=
\
...
...
@@ -104,6 +104,21 @@ parser_test_SOURCES = \
src/util/logging.c
parser_test_CFLAGS
=
-std
=
c99
$(SET_FEATURES)
$(SET_INCLUDES)
uk_dump_SOURCES
=
\
src/devtools/uk_dump.c
\
src/libaacs/unit_key.h
\
src/libaacs/unit_key.c
\
src/util/logging.c
uk_dump_CFLAGS
=
-std
=
c99
$(SET_FEATURES)
$(SET_INCLUDES)
mkb_dump_SOURCES
=
\
src/devtools/mkb_dump.c
\
src/libaacs/mkb.h
\
src/libaacs/mkb.c
\
src/util/strutl.c
\
src/util/logging.c
mkb_dump_CFLAGS
=
-std
=
c99
$(SET_FEATURES)
$(SET_INCLUDES)
aacs_info_SOURCES
=
src/examples/aacs_info.c
aacs_info_CFLAGS
=
-std
=
c99
$(SET_FEATURES)
$(SET_INCLUDES)
aacs_info_LDADD
=
libaacs.la
src/devtools/mkb_dump.c
0 → 100644
View file @
c9c8ad90
/*
* This file is part of libaacs
* Copyright (C) 2020 VideoLAN
*
* 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/>.
*/
#include "util/strutl.h"
#include "util/macro.h"
#include "libaacs/mkb.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include "read_file.h"
static
const
struct
{
uint8_t
type
;
const
char
*
name
;
}
rec_names
[]
=
{
{
0x02
,
"End of media key block"
},
{
0x04
,
"Explicit Subset-Difference"
},
{
0x05
,
"Media Key Data / CVALUE"
},
{
0x07
,
"Subset-Difference Index"
},
{
0x0c
,
"Media Key Variant Data"
},
{
0x10
,
"Type and version"
},
{
0x20
,
"Drive revocation list (AACS1)"
},
{
0x21
,
"Host revocation list (AACS1)"
},
{
0x30
,
"Drive revocation list (AACS2)"
},
{
0x31
,
"Host revocation list (AACS2)"
},
{
0x81
,
"Verify media key / DVALUE"
},
{
0x86
,
"Verify media key / DVALUE (AACS2)"
},
};
static
const
struct
{
uint32_t
type
;
const
char
*
name
;
}
mkb_types
[]
=
{
{
MKB_TYPE_3
,
"Type 3"
},
{
MKB_TYPE_4
,
"Type 4"
},
{
MKB_TYPE_10_CLASS_II
,
"Type 10, class II"
},
{
MKB_20_CATEGORY_C
,
"Type 2.0 Category C"
},
{
MKB_21_CATEGORY_C
,
"Type 2.1 Category C"
},
};
static
const
char
*
rec_name
(
uint8_t
type
)
{
size_t
i
;
for
(
i
=
0
;
i
<
sizeof
(
rec_names
)
/
sizeof
(
rec_names
[
0
]);
i
++
)
if
(
rec_names
[
i
].
type
==
type
)
return
rec_names
[
i
].
name
;
return
"(UNKNOWN)"
;
}
static
const
char
*
type_name
(
uint32_t
type
)
{
size_t
i
;
for
(
i
=
0
;
i
<
sizeof
(
mkb_types
)
/
sizeof
(
mkb_types
[
0
]);
i
++
)
if
(
mkb_types
[
i
].
type
==
type
)
return
mkb_types
[
i
].
name
;
return
"(UNKNOWN)"
;
}
static
void
_dump_signature
(
const
uint8_t
*
sig
,
size_t
len
)
{
size_t
i
;
printf
(
" Signature (%zu bytes): "
,
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
printf
(
"%02x"
,
sig
[
i
]);
}
printf
(
"
\n
"
);
}
static
void
_dump_aacs1_rl
(
const
uint8_t
*
rl
,
size_t
rl_size
)
{
if
(
rl_size
<
4
)
return
;
uint32_t
total_entries
=
MKINT_BE32
(
rl
);
rl
+=
4
;
rl_size
-=
4
;
while
(
total_entries
>
0
&&
rl_size
>=
4
)
{
uint32_t
entries
=
MKINT_BE32
(
rl
);
rl
+=
4
;
rl_size
-=
4
;
if
(
entries
>=
(
0xffffffff
-
8
-
40
)
/
8
)
{
printf
(
" invalid revocation list
\n
"
);
break
;
}
size_t
rec_len
=
8
*
entries
+
40
;
if
(
rec_len
>
rl_size
)
{
printf
(
" revocation list size mismatch
\n
"
);
break
;
}
unsigned
ii
;
for
(
ii
=
0
;
ii
<
entries
;
ii
++
)
{
uint16_t
len
=
MKINT_BE16
(
rl
);
uint64_t
id
=
MKINT_BE48
(
rl
+
2
);
printf
(
" %3d: id %12"
PRIx64
,
ii
,
id
);
if
(
len
)
{
printf
(
"-%12"
PRIx64
,
id
+
len
);
}
printf
(
"
\n
"
);
rl
+=
8
;
rl_size
-=
8
;
}
_dump_signature
(
rl
,
40
);
rl
+=
40
;
rl_size
-=
40
;
total_entries
-=
entries
;
}
}
static
void
_dump_type_and_version
(
const
uint8_t
*
p
,
size_t
size
)
{
if
(
size
>=
4
)
printf
(
" MKB type: 0x%08x (%s)
\n
"
,
MKINT_BE32
(
p
),
type_name
(
MKINT_BE32
(
p
)));
if
(
size
>=
8
)
printf
(
" MKB version: %8d
\n
"
,
MKINT_BE32
(
p
+
4
));
}
static
void
_dump_record
(
MKB
*
mkb
,
int
record
)
{
size_t
size
=
mkb_data_size
(
mkb
);
const
uint8_t
*
data
=
mkb_data
(
mkb
);
size_t
pos
,
len
;
printf
(
"
\n
Record 0x%02x (%s):
\n
"
,
record
,
rec_name
(
record
));
for
(
pos
=
0
;
pos
+
4
<=
size
;
pos
+=
len
)
{
uint8_t
type
=
data
[
pos
];
len
=
MKINT_BE24
(
data
+
pos
+
1
);
if
(
type
==
record
)
{
switch
(
record
)
{
case
0x02
:
_dump_signature
(
data
+
pos
+
4
,
len
-
4
);
break
;
case
0x10
:
_dump_type_and_version
(
data
+
pos
+
4
,
len
-
4
);
break
;
case
0x20
:
case
0x21
:
_dump_aacs1_rl
(
data
+
pos
+
4
,
len
-
4
);
break
;
}
printf
(
" Raw data (%zu bytes):
\n
"
,
len
-
4
);
const
uint8_t
*
p
=
data
+
pos
+
4
;
const
uint8_t
*
e
=
data
+
pos
+
len
;
while
(
p
<
e
)
{
size_t
i
;
printf
(
" "
);
for
(
i
=
0
;
i
<
8
&&
p
<
e
;
i
++
,
p
++
)
printf
(
"%02x "
,
*
p
);
printf
(
" "
);
for
(
i
=
0
;
i
<
8
&&
p
<
e
;
i
++
,
p
++
)
printf
(
"%02x "
,
*
p
);
printf
(
"
\n
"
);
}
break
;
}
}
}
static
void
_list_missing_records
(
const
uint8_t
*
seen_map
)
{
int
type
;
for
(
type
=
0
;
type
<
256
;
type
++
)
{
if
(
!
seen_map
[
type
])
{
size_t
i
;
for
(
i
=
0
;
i
<
sizeof
(
rec_names
)
/
sizeof
(
rec_names
[
0
]);
i
++
)
{
if
(
rec_names
[
i
].
type
==
type
)
{
printf
(
" %s
\n
"
,
rec_names
[
i
].
name
);
}
}
}
}
}
static
void
_list_records
(
MKB
*
mkb
,
uint8_t
*
seen_map
)
{
const
uint8_t
*
data
=
mkb_data
(
mkb
);
size_t
size
=
mkb_data_size
(
mkb
);
size_t
pos
,
len
;
for
(
pos
=
0
;
pos
+
4
<=
size
;
pos
+=
len
)
{
uint8_t
type
=
data
[
pos
];
len
=
MKINT_BE24
(
data
+
pos
+
1
);
printf
(
" record 0x%02x: %10zu bytes %s
\n
"
,
type
,
len
,
rec_name
(
type
));
seen_map
[
type
]
=
1
;
if
(
len
==
0
)
{
printf
(
" UNKNOWN: %10zu bytes
\n
"
,
size
-
pos
);
break
;
}
}
}
int
main
(
int
argc
,
char
**
argv
)
{
MKB
*
mkb
;
uint8_t
seen_map
[
256
]
=
{
0
};
uint8_t
*
data
;
size_t
size
;
int
arg
;
if
(
argc
<
2
)
{
fprintf
(
stderr
,
"usage: mkb_dump <mkb_file> [record [record ...]]
\n
"
);
exit
(
-
1
);
}
size
=
_read_file
(
argv
[
1
],
16
,
1024
*
1024
*
1024
,
&
data
);
if
(
!
size
)
{
exit
(
-
1
);
}
printf
(
"MKB file size: %10zu bytes
\n
"
,
size
);
mkb
=
mkb_init
(
data
,
size
);
if
(
!
mkb
)
{
fprintf
(
stderr
,
"MKB init failed: %s (%d)
\n
"
,
strerror
(
errno
),
errno
);
free
(
data
);
exit
(
-
1
);
}
printf
(
"MKB size: %10zu bytes
\n\n
"
,
mkb_data_size
(
mkb
));
printf
(
"MKB type: %s (0x%08x)
\n
"
,
type_name
(
mkb_type
(
mkb
)),
mkb_type
(
mkb
));
printf
(
"MKB version: %d
\n
"
,
mkb_version
(
mkb
));
printf
(
"MKB records:
\n
"
);
_list_records
(
mkb
,
seen_map
);
printf
(
" PADDING: %10zu bytes
\n
"
,
size
-
mkb_data_size
(
mkb
));
printf
(
"
\n
Not present records:
\n
"
);
_list_missing_records
(
seen_map
);
for
(
arg
=
2
;
arg
<
argc
;
arg
++
)
{
int
record
=
strtol
(
argv
[
arg
],
NULL
,
16
);
_dump_record
(
mkb
,
record
);
}
/* check padding */
for
(
size_t
i
=
mkb_data_size
(
mkb
);
i
<
size
;
i
++
)
{
if
(
data
[
i
])
{
printf
(
"
\n
Data found from padding !
\n
"
);
break
;
}
}
mkb_close
(
mkb
);
return
0
;
}
src/devtools/read_file.h
0 → 100644
View file @
c9c8ad90
/*
* This file is part of libaacs
* Copyright (C) 2020 VideoLAN
*
* 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/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
static
size_t
_read_file
(
const
char
*
name
,
off_t
min_size
,
off_t
max_size
,
uint8_t
**
pdata
)
{
FILE
*
f
;
uint8_t
*
data
=
NULL
;
off_t
file_size
;
size_t
size
;
f
=
fopen
(
name
,
"rb"
);
if
(
!
f
)
{
fprintf
(
stderr
,
"error opening '%s': %s (%d)
\n
"
,
name
,
strerror
(
errno
),
errno
);
return
0
;
}
if
(
fseek
(
f
,
0
,
SEEK_END
)
<
0
)
{
fprintf
(
stderr
,
"error seeking to end: %s (%d)
\n
"
,
strerror
(
errno
),
errno
);
goto
fail
;
}
file_size
=
ftell
(
f
);
if
(
file_size
<
0
)
{
fprintf
(
stderr
,
"error getting file size: %s (%d)
\n
"
,
strerror
(
errno
),
errno
);
goto
fail
;
}
if
(
file_size
<
min_size
||
file_size
>
max_size
)
{
fprintf
(
stderr
,
"weird file size: %lld
\n
"
,
(
long
long
)
file_size
);
goto
fail
;
}
if
(
fseek
(
f
,
0
,
SEEK_SET
)
<
0
)
{
fprintf
(
stderr
,
"error seeking to start: %s (%d)
\n
"
,
strerror
(
errno
),
errno
);
goto
fail
;
}
size
=
(
size_t
)
file_size
;
data
=
malloc
(
size
);
if
(
!
data
)
{
fprintf
(
stderr
,
"error allocating %zu bytes: %s (%d)
\n
"
,
size
,
strerror
(
errno
),
errno
);
goto
fail
;
}
if
(
fread
(
data
,
size
,
1
,
f
)
!=
1
)
{
fprintf
(
stderr
,
"error reading %zu bytes: %s (%d)
\n
"
,
size
,
strerror
(
errno
),
errno
);
goto
fail
;
}
fclose
(
f
);
*
pdata
=
data
;
return
size
;
fail:
free
(
data
);
fclose
(
f
);
return
0
;
}
src/devtools/uk_dump.c
0 → 100644
View file @
c9c8ad90
/*
* This file is part of libaacs
* Copyright (C) 2020 VideoLAN
*
* 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/>.
*/
#include "util/strutl.h"
#include "util/macro.h"
#include "libaacs/unit_key.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "read_file.h"
static
void
_uk_dump
(
AACS_UK
*
uk
)
{
unsigned
i
,
j
;
printf
(
"Num BDMV dir: %d
\n
"
,
uk
->
num_bdmv_dir
);
printf
(
"Application type: %d
\n
"
,
uk
->
app_type
);
printf
(
"Use_SKB_Unified_MKB_Flag: %d
\n
"
,
uk
->
use_skb_mkb
);
printf
(
"Encrypted unit keys: %u
\n
"
,
uk
->
num_uk
);
for
(
i
=
0
;
i
<
uk
->
num_uk
;
i
++
)
{
printf
(
" %u: "
,
i
+
1
);
for
(
j
=
0
;
j
<
16
;
j
++
)
{
printf
(
"%02x"
,
uk
->
enc_uk
[
i
].
key
[
j
]);
}
printf
(
"
\n
"
);
}
printf
(
"Title CPS units (%d titles):
\n
"
,
uk
->
num_titles
);
if
(
uk
->
num_titles
>
0
)
printf
(
" FP: %u
\n
"
,
uk
->
title_cps_unit
[
0
]);
if
(
uk
->
num_titles
>
1
)
printf
(
" TM: %u
\n
"
,
uk
->
title_cps_unit
[
1
]);
for
(
i
=
0
;
i
<
uk
->
num_titles
;
i
++
)
printf
(
" %2u: %u
\n
"
,
i
+
1
,
uk
->
title_cps_unit
[
i
+
2
]);
}
int
main
(
int
argc
,
char
**
argv
)
{
AACS_UK
*
uk
;
uint8_t
*
data
;
size_t
size
;
int
aacs2
=
argc
>
2
;
size_t
l
,
b
;
if
(
argc
<
2
)
{
fprintf
(
stderr
,
"usage: uk_dump <Unit_Key_RO.inf> [AACS2]
\n
"
);
exit
(
-
1
);
}
size
=
_read_file
(
argv
[
1
],
16
,
1024
*
1024
,
&
data
);
if
(
!
size
)
{
exit
(
-
1
);
}
printf
(
"Unit key file size: %8zu bytes
\n
"
,
size
);
uk
=
uk_parse
(
data
,
size
,
aacs2
);
if
(
!
uk
)
{
fprintf
(
stderr
,
"Parsing failed
\n
"
);
exit
(
-
1
);
}
_uk_dump
(
uk
);
printf
(
"Raw data:
\n
"
);
uint32_t
mask
=
0
;
for
(
l
=
0
;
l
<
size
;
l
+=
16
)
{
mask
<<=
8
;
for
(
b
=
0
;
b
<
32
&&
l
+
b
<
size
;
b
++
)
mask
|=
data
[
l
+
b
];
if
(
mask
)
{
printf
(
"%04lx: "
,
(
long
)
l
);
for
(
b
=
0
;
b
<
8
&&
l
+
b
<
size
;
b
++
)
printf
(
"%02x "
,
data
[
l
+
b
]);
printf
(
" "
);
for
(
b
=
8
;
b
<
16
&&
l
+
b
<
size
;
b
++
)
printf
(
"%02x "
,
data
[
l
+
b
]);
printf
(
" "
);
for
(
b
=
0
;
b
<
8
&&
l
+
b
<
size
;
b
++
)
if
(
data
[
l
+
b
])
printf
(
"%02x "
,
data
[
l
+
b
]);
else
printf
(
" "
);
printf
(
" "
);
for
(
b
=
8
;
b
<
16
&&
l
+
b
<
size
;
b
++
)
if
(
data
[
l
+
b
])
printf
(
"%02x "
,
data
[
l
+
b
]);
else
printf
(
" "
);
printf
(
"
\n
"
);
}
}
uk_free
(
&
uk
);
free
(
data
);
return
0
;
}
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