Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Jean-Baptiste Kempf
libaacs
Commits
923c8861
Commit
923c8861
authored
Oct 15, 2013
by
npzacs
Browse files
Factorize common code
parent
07e540c9
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/libaacs/aacs.c
View file @
923c8861
...
...
@@ -273,13 +273,8 @@ static MKB *_get_hrl_mkb(MMC *mmc)
return
mkb
;
}
static
int
_read_
vid
(
AACS
*
aacs
,
cert_list
*
hcl
)
static
int
_mmc
_read_
auth
(
AACS
*
aacs
,
cert_list
*
hcl
,
int
type
,
uint8_t
*
p1
,
uint8_t
*
p2
)
{
/* Use VID given in config file if available */
if
(
memcmp
(
aacs
->
vid
,
empty_key
,
16
))
{
return
AACS_SUCCESS
;
}
MMC
*
mmc
=
NULL
;
if
(
!
(
mmc
=
mmc_open
(
aacs
->
path
)))
{
return
AACS_ERROR_MMC_OPEN
;
...
...
@@ -319,13 +314,11 @@ static int _read_vid(AACS *aacs, cert_list *hcl)
DEBUG
(
DBG_AACS
,
"Trying host certificate (id 0x%s)...
\n
"
,
print_hex
(
tmp_str
,
cert
+
4
,
6
));
int
mmc_result
=
mmc_read_
vid
(
mmc
,
priv_key
,
cert
,
aacs
->
vid
);
int
mmc_result
=
mmc_read_
auth
(
mmc
,
priv_key
,
cert
,
type
,
p1
,
p2
);
switch
(
mmc_result
)
{
case
MMC_SUCCESS
:
mkb_close
(
hrl_mkb
);
mmc_close
(
mmc
);
/* cache vid */
keycache_save
(
"vid"
,
aacs
->
disc_id
,
aacs
->
vid
,
16
);
return
AACS_SUCCESS
;
case
MMC_ERROR_CERT_REVOKED
:
error_code
=
AACS_ERROR_CERT_REVOKED
;
...
...
@@ -340,107 +333,42 @@ static int _read_vid(AACS *aacs, cert_list *hcl)
mkb_close
(
hrl_mkb
);
mmc_close
(
mmc
);
DEBUG
(
DBG_AACS
,
"Error reading VID!
\n
"
);
return
error_code
;
}
static
int
_read_
read_data_key
(
AACS
*
aacs
,
cert_list
*
hcl
)
static
int
_read_
vid
(
AACS
*
aacs
,
cert_list
*
hcl
)
{
MMC
*
mmc
=
NULL
;
if
(
!
(
mmc
=
mmc_open
(
aacs
->
path
)
))
{
return
AACS_
ERROR_MMC_OPEN
;
/* Use VID given in config file if available */
if
(
memcmp
(
aacs
->
vid
,
empty_key
,
16
))
{
return
AACS_
SUCCESS
;
}
int
error_code
=
AACS_ERROR_NO_CERT
;
for
(;
hcl
&&
hcl
->
host_priv_key
&&
hcl
->
host_cert
;
hcl
=
hcl
->
next
)
{
char
tmp_str
[
2
*
92
+
1
];
uint8_t
priv_key
[
20
],
cert
[
92
];
hexstring_to_hex_array
(
priv_key
,
sizeof
(
priv_key
),
hcl
->
host_priv_key
);
hexstring_to_hex_array
(
cert
,
sizeof
(
cert
),
hcl
->
host_cert
);
if
(
!
crypto_aacs_verify_host_cert
(
cert
))
{
DEBUG
(
DBG_AACS
,
"Not using invalid host certificate %s.
\n
"
,
print_hex
(
tmp_str
,
cert
,
92
));
continue
;
}
DEBUG
(
DBG_AACS
,
"Trying host certificate (id 0x%s)...
\n
"
,
print_hex
(
tmp_str
,
cert
+
4
,
6
));
int
mmc_result
=
mmc_read_data_keys
(
mmc
,
priv_key
,
cert
,
aacs
->
read_data_key
,
NULL
);
switch
(
mmc_result
)
{
case
MMC_SUCCESS
:
mmc_close
(
mmc
);
return
AACS_SUCCESS
;
case
MMC_ERROR_CERT_REVOKED
:
error_code
=
AACS_ERROR_CERT_REVOKED
;
break
;
case
MMC_ERROR
:
default:
error_code
=
AACS_ERROR_MMC_FAILURE
;
break
;
}
int
error_code
=
_mmc_read_auth
(
aacs
,
hcl
,
MMC_READ_VID
,
aacs
->
vid
,
NULL
);
if
(
error_code
!=
AACS_SUCCESS
)
{
DEBUG
(
DBG_AACS
,
"Error reading VID!
\n
"
);
}
else
{
/* cache vid */
keycache_save
(
"vid"
,
aacs
->
disc_id
,
aacs
->
vid
,
16
);
}
mmc_close
(
mmc
);
DEBUG
(
DBG_AACS
,
"Error reading read data key!
\n
"
);
return
error_code
;
}
static
int
_read_
pmsn
(
AACS
*
aacs
,
cert_list
*
hcl
)
static
int
_read_
read_data_key
(
AACS
*
aacs
,
cert_list
*
hcl
)
{
MMC
*
mmc
=
NULL
;
if
(
!
(
mmc
=
mmc_open
(
aacs
->
path
))
)
{
return
AACS_ERROR_MMC_OPEN
;
int
error_code
=
_mmc_read_auth
(
aacs
,
hcl
,
MMC_READ_DATA_KEYS
,
aacs
->
read_data_key
,
NULL
)
;
if
(
error_code
!=
AACS_SUCCESS
)
{
DEBUG
(
DBG_AACS
,
"Error reading data keys!
\n
"
)
;
}
return
error_code
;
}
int
error_code
=
AACS_ERROR_NO_CERT
;
const
uint8_t
*
drive_cert
=
mmc_get_drive_cert
(
mmc
);
for
(;
hcl
&&
hcl
->
host_priv_key
&&
hcl
->
host_cert
;
hcl
=
hcl
->
next
)
{
char
tmp_str
[
2
*
92
+
1
];
uint8_t
priv_key
[
20
],
cert
[
92
];
hexstring_to_hex_array
(
priv_key
,
sizeof
(
priv_key
),
hcl
->
host_priv_key
);
hexstring_to_hex_array
(
cert
,
sizeof
(
cert
),
hcl
->
host_cert
);
if
(
!
crypto_aacs_verify_host_cert
(
cert
))
{
DEBUG
(
DBG_AACS
,
"Not using invalid host certificate %s.
\n
"
,
print_hex
(
tmp_str
,
cert
,
92
));
continue
;
}
if
(
drive_cert
&&
(
drive_cert
[
1
]
&
0x01
)
&&
!
(
cert
[
1
]
&
0x01
))
{
DEBUG
(
DBG_AACS
,
"Certificate (id 0x%s) does not support bus encryption
\n
"
,
print_hex
(
tmp_str
,
cert
+
4
,
6
));
//continue;
}
DEBUG
(
DBG_AACS
,
"Trying host certificate (id 0x%s)...
\n
"
,
print_hex
(
tmp_str
,
cert
+
4
,
6
));
int
mmc_result
=
mmc_read_pmsn
(
mmc
,
priv_key
,
cert
,
aacs
->
pmsn
);
switch
(
mmc_result
)
{
case
MMC_SUCCESS
:
mmc_close
(
mmc
);
return
AACS_SUCCESS
;
case
MMC_ERROR_CERT_REVOKED
:
error_code
=
AACS_ERROR_CERT_REVOKED
;
break
;
case
MMC_ERROR
:
default:
error_code
=
AACS_ERROR_MMC_FAILURE
;
break
;
}
static
int
_read_pmsn
(
AACS
*
aacs
,
cert_list
*
hcl
)
{
int
error_code
=
_mmc_read_auth
(
aacs
,
hcl
,
MMC_READ_PMSN
,
aacs
->
pmsn
,
NULL
);
fprintf
(
stderr
,
"pmsn read 2
\n
"
);
if
(
error_code
!=
AACS_SUCCESS
)
{
DEBUG
(
DBG_AACS
,
"Error reading PMSN!
\n
"
);
}
mmc_close
(
mmc
);
DEBUG
(
DBG_AACS
,
"Error reading PMSN!
\n
"
);
return
error_code
;
}
...
...
src/libaacs/mmc.c
View file @
923c8861
...
...
@@ -1015,6 +1015,10 @@ void mmc_close(MMC *mmc)
}
}
/*
*
*/
static
int
_verify_signature
(
const
uint8_t
*
cert
,
const
uint8_t
*
signature
,
const
uint8_t
*
nonce
,
const
uint8_t
*
point
)
{
...
...
@@ -1113,27 +1117,17 @@ static int _mmc_aacs_auth(MMC *mmc, uint8_t agid, const uint8_t *host_priv_key,
return
MMC_SUCCESS
;
}
int
mmc_read_vid
(
MMC
*
mmc
,
const
uint8_t
*
host_priv_key
,
const
uint8_t
*
host_cert
,
uint8_t
*
vid
)
/*
*
*/
static
int
_read_vid
(
MMC
*
mmc
,
uint8_t
agid
,
const
uint8_t
*
bus_key
,
uint8_t
*
vid
)
{
uint8_t
agid
=
0
,
mac
[
16
],
calc_mac
[
16
]
,
bus_key
[
16
]
;
uint8_t
mac
[
16
],
calc_mac
[
16
];
char
str
[
512
];
int
error_code
;
DEBUG
(
DBG_MMC
,
"Reading VID from drive...
\n
"
);
_mmc_invalidate_agids
(
mmc
);
if
(
!
_mmc_report_agid
(
mmc
,
&
agid
))
{
DEBUG
(
DBG_MMC
|
DBG_CRIT
,
"Didn't get AGID from drive
\n
"
);
return
MMC_ERROR
;
}
DEBUG
(
DBG_MMC
,
"Got AGID from drive: %d
\n
"
,
agid
);
error_code
=
_mmc_aacs_auth
(
mmc
,
agid
,
host_priv_key
,
host_cert
,
bus_key
);
if
(
error_code
)
{
return
error_code
;
}
if
(
_mmc_read_vid
(
mmc
,
agid
,
vid
,
mac
))
{
if
(
DEBUG_KEYS
)
{
DEBUG
(
DBG_MMC
,
"VID : %s
\n
"
,
print_hex
(
str
,
vid
,
16
));
...
...
@@ -1146,39 +1140,21 @@ int mmc_read_vid(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cer
DEBUG
(
DBG_MMC
|
DBG_CRIT
,
"VID MAC is incorrect. This means this Volume ID is not correct.
\n
"
);
}
_mmc_invalidate_agid
(
mmc
,
agid
);
return
MMC_SUCCESS
;
}
DEBUG
(
DBG_MMC
|
DBG_CRIT
,
"Unable to read VID from drive!
\n
"
);
_mmc_invalidate_agid
(
mmc
,
agid
);
return
MMC_ERROR
;
}
int
mmc
_read_pmsn
(
MMC
*
mmc
,
const
uint8_t
*
host_priv_key
,
const
uint8_t
*
host_cert
,
uint8_t
*
pmsn
)
static
int
_read_pmsn
(
MMC
*
mmc
,
uint8_t
agid
,
const
uint8_t
*
bus_key
,
uint8_t
*
pmsn
)
{
uint8_t
agid
=
0
,
mac
[
16
],
calc_mac
[
16
]
,
bus_key
[
16
]
;
uint8_t
mac
[
16
],
calc_mac
[
16
];
char
str
[
512
];
int
error_code
;
DEBUG
(
DBG_MMC
,
"Reading PMSN from drive...
\n
"
);
_mmc_invalidate_agids
(
mmc
);
if
(
!
_mmc_report_agid
(
mmc
,
&
agid
))
{
DEBUG
(
DBG_MMC
|
DBG_CRIT
,
"Didn't get AGID from drive
\n
"
);
return
MMC_ERROR
;
}
DEBUG
(
DBG_MMC
,
"Got AGID from drive: %d
\n
"
,
agid
);
error_code
=
_mmc_aacs_auth
(
mmc
,
agid
,
host_priv_key
,
host_cert
,
bus_key
);
if
(
error_code
)
{
return
error_code
;
}
if
(
_mmc_read_pmsn
(
mmc
,
agid
,
pmsn
,
mac
))
{
if
(
DEBUG_KEYS
)
{
DEBUG
(
DBG_MMC
,
"PMSN : %s
\n
"
,
print_hex
(
str
,
pmsn
,
16
));
...
...
@@ -1191,26 +1167,50 @@ int mmc_read_pmsn(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_ce
DEBUG
(
DBG_MMC
|
DBG_CRIT
,
"PMSN MAC is incorrect. This means this Pre-recorded Medial Serial Number is not correct.
\n
"
);
}
_mmc_invalidate_agid
(
mmc
,
agid
);
return
MMC_SUCCESS
;
}
DEBUG
(
DBG_MMC
|
DBG_CRIT
,
"Unable to read PMSN from drive!
\n
"
);
_mmc_invalidate_agid
(
mmc
,
agid
);
return
MMC_ERROR
;
}
int
mmc_read_data_keys
(
MMC
*
mmc
,
const
uint8_t
*
host_priv_key
,
const
uint8_t
*
host_cert
,
uint8_t
*
read_data_key
,
uint8_t
*
write_data_key
)
static
int
_read_data_keys
(
MMC
*
mmc
,
uint8_t
agid
,
const
uint8_t
*
bus_key
,
uint8_t
*
read_data_key
,
uint8_t
*
write_data_key
)
{
uint8_t
agid
=
0
,
bus_key
[
16
],
encrypted_read_data_key
[
16
],
encrypted_write_data_key
[
16
];
uint8_t
encrypted_read_data_key
[
16
],
encrypted_write_data_key
[
16
];
char
str
[
512
];
int
error_code
;
DEBUG
(
DBG_MMC
,
"Reading data keys from drive...
\n
"
);
if
(
_mmc_read_data_keys
(
mmc
,
agid
,
encrypted_read_data_key
,
encrypted_write_data_key
))
{
if
(
read_data_key
)
{
crypto_aes128d
(
bus_key
,
encrypted_read_data_key
,
read_data_key
);
if
(
DEBUG_KEYS
)
{
DEBUG
(
DBG_MMC
,
"READ DATA KEY : %s
\n
"
,
print_hex
(
str
,
read_data_key
,
16
));
}
}
if
(
write_data_key
)
{
crypto_aes128d
(
bus_key
,
encrypted_write_data_key
,
write_data_key
);
if
(
DEBUG_KEYS
)
{
DEBUG
(
DBG_MMC
,
"WRITE DATA KEY : %s
\n
"
,
print_hex
(
str
,
write_data_key
,
16
));
}
}
return
MMC_SUCCESS
;
}
DEBUG
(
DBG_MMC
|
DBG_CRIT
,
"Unable to read data keys from drive!
\n
"
);
return
MMC_ERROR
;
}
int
mmc_read_auth
(
MMC
*
mmc
,
const
uint8_t
*
host_priv_key
,
const
uint8_t
*
host_cert
,
int
request
,
uint8_t
*
p1
,
uint8_t
*
p2
)
{
uint8_t
agid
=
0
,
bus_key
[
16
];
int
error_code
;
_mmc_invalidate_agids
(
mmc
);
if
(
!
_mmc_report_agid
(
mmc
,
&
agid
))
{
...
...
@@ -1226,35 +1226,35 @@ int mmc_read_data_keys(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *ho
error_code
=
_mmc_aacs_auth
(
mmc
,
agid
,
host_priv_key
,
host_cert
,
bus_key
);
if
(
error_code
)
{
_mmc_invalidate_agid
(
mmc
,
agid
);
return
error_code
;
}
if
(
_mmc_read_data_keys
(
mmc
,
agid
,
encrypted_read_data_key
,
encrypted_write_data_key
))
{
if
(
read_data_key
)
{
crypto_aes128d
(
bus_key
,
encrypted_read_data_key
,
read_data_key
);
if
(
DEBUG_KEYS
)
{
DEBUG
(
DBG_MMC
,
"READ DATA KEY : %s
\n
"
,
print_hex
(
str
,
read_data_key
,
16
));
}
}
if
(
write_data_key
)
{
crypto_aes128d
(
bus_key
,
encrypted_write_data_key
,
write_data_key
);
if
(
DEBUG_KEYS
)
{
DEBUG
(
DBG_MMC
,
"WRITE DATA KEY : %s
\n
"
,
print_hex
(
str
,
write_data_key
,
16
));
}
}
_mmc_invalidate_agid
(
mmc
,
agid
);
return
MMC_SUCCESS
;
switch
(
request
)
{
case
MMC_READ_VID
:
error_code
=
_read_vid
(
mmc
,
agid
,
bus_key
,
p1
);
break
;
case
MMC_READ_PMSN
:
error_code
=
_read_pmsn
(
mmc
,
agid
,
bus_key
,
p1
);
break
;
case
MMC_READ_DATA_KEYS
:
error_code
=
_read_data_keys
(
mmc
,
agid
,
bus_key
,
p1
,
p2
);
break
;
default:
DEBUG
(
DBG_MMC
|
DBG_CRIT
,
"unknown mmc_read_auth() request %d
\n
"
,
request
);
error_code
=
MMC_ERROR
;
break
;
}
DEBUG
(
DBG_MMC
|
DBG_CRIT
,
"Unable to read data keys from drive!
\n
"
);
_mmc_invalidate_agid
(
mmc
,
agid
);
return
MMC_ERROR
;
return
error_code
;
}
/*
*
*/
int
mmc_read_drive_cert
(
MMC
*
mmc
,
uint8_t
*
drive_cert
)
{
uint8_t
buf
[
116
];
...
...
src/libaacs/mmc.h
View file @
923c8861
...
...
@@ -31,14 +31,14 @@ typedef struct mmc MMC;
#define MMC_ERROR -1
/* MMC failed */
#define MMC_ERROR_CERT_REVOKED -2
/* revoked certificate */
#define MMC_READ_VID 0
#define MMC_READ_PMSN 1
#define MMC_READ_DATA_KEYS 2
AACS_PRIVATE
MMC
*
mmc_open
(
const
char
*
path
);
AACS_PRIVATE
void
mmc_close
(
MMC
*
mmc
);
AACS_PRIVATE
int
mmc_read_vid
(
MMC
*
mmc
,
const
uint8_t
*
host_priv_key
,
const
uint8_t
*
host_cert
,
uint8_t
*
vid
);
AACS_PRIVATE
int
mmc_read_pmsn
(
MMC
*
mmc
,
const
uint8_t
*
host_priv_key
,
const
uint8_t
*
host_cert
,
uint8_t
*
pmsn
);
AACS_PRIVATE
int
mmc_read_data_keys
(
MMC
*
mmc
,
const
uint8_t
*
host_priv_key
,
const
uint8_t
*
host_cert
,
uint8_t
*
read_data_key
,
uint8_t
*
write_data_key
);
AACS_PRIVATE
int
mmc_read_auth
(
MMC
*
mmc
,
const
uint8_t
*
host_priv_key
,
const
uint8_t
*
host_cert
,
int
request
,
uint8_t
*
p1
,
uint8_t
*
p2
);
AACS_PRIVATE
int
mmc_read_drive_cert
(
MMC
*
mmc
,
uint8_t
*
drive_cert
);
AACS_PRIVATE
const
uint8_t
*
mmc_get_drive_cert
(
MMC
*
mmc
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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