Clean HCA subkey code

This commit is contained in:
bnnm 2021-12-11 12:43:06 +01:00
parent bda98d71e1
commit 05cdd0bbf5
3 changed files with 13 additions and 26 deletions

View File

@ -338,7 +338,7 @@ typedef struct {
} hca_keytest_t;
void test_hca_key(hca_codec_data* data, hca_keytest_t* hk);
void hca_set_encryption_key(hca_codec_data* data, uint64_t keycode);
void hca_set_encryption_key(hca_codec_data* data, uint64_t keycode, uint64_t subkey);
STREAMFILE* hca_get_streamfile(hca_codec_data* data);

View File

@ -209,7 +209,7 @@ STREAMFILE* hca_get_streamfile(hca_codec_data* data) {
/* Test a number of frames if key decrypts correctly.
* Returns score: <0: error/wrong, 0: unknown/silent file, >0: good (the closest to 1 the better). */
static int test_hca_score(hca_codec_data* data, hca_keytest_t* hk, unsigned long long keycode) {
static int test_hca_score(hca_codec_data* data, hca_keytest_t* hk) {
size_t test_frames = 0, current_frame = 0, blank_frames = 0;
int total_score = 0;
const unsigned int block_size = data->info.blockSize;
@ -222,7 +222,7 @@ static int test_hca_score(hca_codec_data* data, hca_keytest_t* hk, unsigned long
* Buffered IO seems fast enough (not very different reading a large block once vs frame by frame).
* clHCA_TestBlock could be optimized a bit more. */
clHCA_SetKey(data->handle, keycode);
hca_set_encryption_key(data, hk->key, hk->subkey);
/* Test up to N non-blank frames or until total frames. */
/* A final score of 0 (=silent) is only possible for short files with all blank frames */
@ -289,35 +289,26 @@ static int test_hca_score(hca_codec_data* data, hca_keytest_t* hk, unsigned long
void test_hca_key(hca_codec_data* data, hca_keytest_t* hk) {
int score;
uint64_t key = hk->key;
uint16_t subkey = hk->subkey;
//;VGM_LOG("HCA: test key=%08x%08x, subkey=%04x\n",
// (uint32_t)((key >> 32) & 0xFFFFFFFF), (uint32_t)(key & 0xFFFFFFFF), subkey);
if (subkey) {
key = key * ( ((uint64_t)subkey << 16u) | ((uint16_t)~subkey + 2u) );
}
score = test_hca_score(data, hk, (unsigned long long)key);
score = test_hca_score(data, hk);
//;VGM_LOG("HCA: test key=%08x%08x, subkey=%04x, score=%i\n",
// (uint32_t)((key >> 32) & 0xFFFFFFFF), (uint32_t)(key & 0xFFFFFFFF), subkey, score);
// (uint32_t)((hk->key >> 32) & 0xFFFFFFFF), (uint32_t)(hk->key & 0xFFFFFFFF), hk->subkey, score);
/* wrong key */
if (score < 0)
return;
//;VGM_LOG("HCA: ok key=%08x%08x, subkey=%04x, score=%i\n",
// (uint32_t)((key >> 32) & 0xFFFFFFFF), (uint32_t)(key & 0xFFFFFFFF), subkey, score);
/* update if something better is found */
if (hk->best_score <= 0 || (score < hk->best_score && score > 0)) {
hk->best_score = score;
hk->best_key = key;
hk->best_key = hk->key; /* base */
}
}
void hca_set_encryption_key(hca_codec_data* data, uint64_t keycode) {
void hca_set_encryption_key(hca_codec_data* data, uint64_t keycode, uint64_t subkey) {
if (subkey) {
keycode = keycode * ( ((uint64_t)subkey << 16u) | ((uint16_t)~subkey + 2u) );
}
clHCA_SetKey(data->handle, (unsigned long long)keycode);
}

View File

@ -49,14 +49,10 @@ VGMSTREAM* init_vgmstream_hca_subkey(STREAMFILE* sf, uint16_t subkey) {
keysize = read_key_file(keybuf, 0x08+0x04, sf);
if (keysize == 0x08) { /* standard */
keycode = get_u64be(keybuf+0x00);
if (subkey) {
keycode = keycode * ( ((uint64_t)subkey << 16u) | ((uint16_t)~subkey + 2u) );
}
}
else if (keysize == 0x08+0x02) { /* seed key + AWB subkey */
uint64_t file_key = get_u64be(keybuf+0x00);
uint16_t file_sub = get_u16be(keybuf+0x08);
keycode = file_key * ( ((uint64_t)file_sub << 16u) | ((uint16_t)~file_sub + 2u) );
keycode = get_u64be(keybuf+0x00);
subkey = get_u16be(keybuf+0x08);
}
#ifdef HCA_BRUTEFORCE
else if (1) {
@ -69,7 +65,7 @@ VGMSTREAM* init_vgmstream_hca_subkey(STREAMFILE* sf, uint16_t subkey) {
find_hca_key(hca_data, &keycode, subkey);
}
hca_set_encryption_key(hca_data, keycode);
hca_set_encryption_key(hca_data, keycode, subkey);
}