mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-28 02:55:49 +01:00
Merge pull request #1486 from bnnm/key-aifc
- Fix buggy AIFC [Cro-Mag Rally (Mac)] - Fix TXTP loop_mode keep - Allow text keycode in adxkey/hcakey
This commit is contained in:
commit
4f3dee8e9b
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
# gets all files and updates .am scripts to avoid having to do manually (frowned upon by automake, whatevs)
|
# gets all files and updates .am scripts to avoid having to do manually (frowned upon by automake, whatevs)
|
||||||
# maybe there is a better way or place for this
|
# maybe there is a better way or place for this
|
||||||
VGMSTREAM_SRCS=`(cd ./src/ && ls *.c */*.c) | tr '\n' ' '`
|
VGMSTREAM_SRCS=`(cd ./src/ && ls *.c */*.c */*/*.c) | tr '\n' ' '`
|
||||||
VGMSTREAM_HDRS=`(cd ./src/ && ls *.h */*.h) | tr '\n' ' '`
|
VGMSTREAM_HDRS=`(cd ./src/ && ls *.h */*.h */*/*.h) | tr '\n' ' '`
|
||||||
AUDACIOUS_SRCS=`(cd ./audacious/ && ls *.cc) | tr '\n' ' '`
|
AUDACIOUS_SRCS=`(cd ./audacious/ && ls *.cc) | tr '\n' ' '`
|
||||||
AUDACIOUS_HDRS=`(cd ./audacious/ && ls *.h) | tr '\n' ' '`
|
AUDACIOUS_HDRS=`(cd ./audacious/ && ls *.h) | tr '\n' ' '`
|
||||||
|
|
||||||
|
@ -1944,22 +1944,22 @@ Reminder of some extra formats and helper files vgmstream supports. They are des
|
|||||||
in detail in USAGE.md.
|
in detail in USAGE.md.
|
||||||
|
|
||||||
- artificial headers:
|
- artificial headers:
|
||||||
- .txth (text header, adds support to lots of extra formats)
|
- .txth (text header, adds support to lots of extra formats)
|
||||||
- .genh (generic header, deprecated)
|
- .txtp (text play config, per song segment/layer manipulation)
|
||||||
|
- .txtm (text map config, for formats that open companion files manually)
|
||||||
|
- .genh (generic header, deprecated)
|
||||||
- loop assists:
|
- loop assists:
|
||||||
- .txtm (text map config, for formats that open companion files manually)
|
- .mus (playlist for .acm)
|
||||||
- .txtp (text play config, per song segment/layer manipulation)
|
- .pos (loop info for .wav)
|
||||||
- loop assists:
|
- .sli (loop info for .ogg)
|
||||||
- .mus (playlist for .acm)
|
- .sfl (loop info for .ogg)
|
||||||
- .pos (loop info for .wav)
|
|
||||||
- .sli (loop info for .ogg)
|
|
||||||
- .sfl (loop info for .ogg)
|
|
||||||
- other:
|
- other:
|
||||||
- .adxkey (decryption key for .adx)
|
- .adxkey (decryption key for .adx)
|
||||||
- .ahxkey (decryption key for .ahx)
|
- .ahxkey (decryption key for .ahx)
|
||||||
- .hcakey (decryption key for .hca)
|
- .hcakey (decryption key for .hca)
|
||||||
- .fsbkey (decryption key for .fsb)
|
- .fsbkey (decryption key for .fsb)
|
||||||
- .bnsfkey (decryption key for .bnsf)
|
- .bnsfkey (decryption key for .bnsf)
|
||||||
|
- .awckey (decryption key for .awc)
|
||||||
|
|
||||||
|
|
||||||
## Supported codecs
|
## Supported codecs
|
||||||
|
@ -404,11 +404,11 @@ Regular formats without companion files should work fine in upper/lowercase. For
|
|||||||
Certain formats have encrypted data, and need a key to decrypt. vgmstream
|
Certain formats have encrypted data, and need a key to decrypt. vgmstream
|
||||||
will try to find the correct key from a list, but it can be provided by
|
will try to find the correct key from a list, but it can be provided by
|
||||||
a companion file:
|
a companion file:
|
||||||
- `.adx`: `.adxkey` (keystring, 8-byte keycode, or derived 6 byte start/mult/add key)
|
- `.adx`: `.adxkey` (keystring, or 8-byte keycode, or derived 6 byte start/mult/add key)
|
||||||
- `.ahx`: `.ahxkey` (keystring, or derived 6-byte start/mult/add key)
|
- `.ahx`: `.ahxkey` (keystring, or derived 6-byte start/mult/add key)
|
||||||
- `.hca`: `.hcakey` (8-byte decryption key, a 64-bit number)
|
- `.hca`: `.hcakey` (keystring, or 8-byte keycode, a 64-bit number)
|
||||||
- `.awb`/`.acb` also may use `.hcakey`, and will combine with an internal AWB subkey
|
- May set 8-byte key followed a 2-byte AWB subkey for newer HCA
|
||||||
- May set a 8-byte key followed a 2-byte AWB subkey for newer HCA
|
- `.awb`/`.acb` also may use `.adxkey`/`.hcakey`, and will combine with an internal AWB subkey
|
||||||
- `.fsb`: `.fsbkey` (decryption key in hex, usually between 8-32 bytes)
|
- `.fsb`: `.fsbkey` (decryption key in hex, usually between 8-32 bytes)
|
||||||
- `.bnsf`: `.bnsfkey` (decryption key, a string up to 24 chars)
|
- `.bnsf`: `.bnsfkey` (decryption key, a string up to 24 chars)
|
||||||
- `.awc`: `.awckey` (decryption key, 0x10 bytes divided into 4 BE ints)
|
- `.awc`: `.awckey` (decryption key, 0x10 bytes divided into 4 BE ints)
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#define ADX_KEY_MAX_TEST_FRAMES 32768
|
#define ADX_KEY_MAX_TEST_FRAMES 32768
|
||||||
#define ADX_KEY_TEST_BUFFER_SIZE 0x8000
|
#define ADX_KEY_TEST_BUFFER_SIZE 0x8000
|
||||||
|
|
||||||
static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t* xor_start, uint16_t* xor_mult, uint16_t* xor_add, uint16_t subkey);
|
static bool find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t* xor_start, uint16_t* xor_mult, uint16_t* xor_add, uint16_t subkey);
|
||||||
|
|
||||||
VGMSTREAM* init_vgmstream_adx(STREAMFILE* sf) {
|
VGMSTREAM* init_vgmstream_adx(STREAMFILE* sf) {
|
||||||
return init_vgmstream_adx_subkey(sf, 0);
|
return init_vgmstream_adx_subkey(sf, 0);
|
||||||
@ -87,7 +87,6 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
|
|||||||
|
|
||||||
/* encryption */
|
/* encryption */
|
||||||
if (version == 0x0408) {
|
if (version == 0x0408) {
|
||||||
|
|
||||||
if (!find_adx_key(sf, 8, &xor_start, &xor_mult, &xor_add, 0)) {
|
if (!find_adx_key(sf, 8, &xor_start, &xor_mult, &xor_add, 0)) {
|
||||||
vgm_logi("ADX: decryption keystring not found\n");
|
vgm_logi("ADX: decryption keystring not found\n");
|
||||||
}
|
}
|
||||||
@ -265,7 +264,7 @@ fail:
|
|||||||
|
|
||||||
/* ADX key detection works by reading XORed ADPCM scales in frames, and un-XORing with keys in
|
/* ADX key detection works by reading XORed ADPCM scales in frames, and un-XORing with keys in
|
||||||
* a list. If resulting values are within the expected range for N scales we accept that key. */
|
* a list. If resulting values are within the expected range for N scales we accept that key. */
|
||||||
static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint16_t *xor_mult, uint16_t *xor_add, uint16_t subkey) {
|
static bool find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint16_t *xor_mult, uint16_t *xor_add, uint16_t subkey) {
|
||||||
const int frame_size = 0x12;
|
const int frame_size = 0x12;
|
||||||
uint16_t *scales = NULL;
|
uint16_t *scales = NULL;
|
||||||
uint16_t *prescales = NULL;
|
uint16_t *prescales = NULL;
|
||||||
@ -280,7 +279,7 @@ static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint1
|
|||||||
size_t key_size;
|
size_t key_size;
|
||||||
|
|
||||||
/* handle type8 keystrings, key9 keycodes and derived keys too */
|
/* handle type8 keystrings, key9 keycodes and derived keys too */
|
||||||
key_size = read_key_file(keybuf, sizeof(keybuf), sf);
|
key_size = read_key_file(keybuf, sizeof(keybuf) - 1, sf);
|
||||||
|
|
||||||
if (key_size > 0) {
|
if (key_size > 0) {
|
||||||
int is_keystring = 0;
|
int is_keystring = 0;
|
||||||
@ -288,28 +287,37 @@ static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint1
|
|||||||
if (type == 8) {
|
if (type == 8) {
|
||||||
is_keystring = cri_key8_valid_keystring(keybuf, key_size);
|
is_keystring = cri_key8_valid_keystring(keybuf, key_size);
|
||||||
}
|
}
|
||||||
|
else if (type == 9) {
|
||||||
|
is_keystring = cri_key9_valid_keystring(keybuf, key_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (key_size == 0x06 && !is_keystring) {
|
if (key_size == 0x06 && !is_keystring) {
|
||||||
*xor_start = get_u16be(keybuf + 0x00);
|
*xor_start = get_u16be(keybuf + 0x00);
|
||||||
*xor_mult = get_u16be(keybuf + 0x02);
|
*xor_mult = get_u16be(keybuf + 0x02);
|
||||||
*xor_add = get_u16be(keybuf + 0x04);
|
*xor_add = get_u16be(keybuf + 0x04);
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
else if (type == 8 && is_keystring) {
|
else if (type == 8 && is_keystring) {
|
||||||
const char* keystring = (const char*)keybuf;
|
const char* keystring = (const char*)keybuf;
|
||||||
cri_key8_derive(keystring, xor_start, xor_mult, xor_add);
|
cri_key8_derive(keystring, xor_start, xor_mult, xor_add);
|
||||||
return 1;
|
return true;
|
||||||
|
}
|
||||||
|
else if (type == 9 && is_keystring) {
|
||||||
|
const char* keystring = (const char*)keybuf;
|
||||||
|
uint64_t keycode = strtoull(keystring, NULL, 10);
|
||||||
|
cri_key9_derive(keycode, subkey, xor_start, xor_mult, xor_add);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (type == 9 && key_size == 0x08) {
|
else if (type == 9 && key_size == 0x08) {
|
||||||
uint64_t keycode = get_u64be(keybuf);
|
uint64_t keycode = get_u64be(keybuf);
|
||||||
cri_key9_derive(keycode, subkey, xor_start, xor_mult, xor_add);
|
cri_key9_derive(keycode, subkey, xor_start, xor_mult, xor_add);
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
else if (type == 9 && key_size == 0x08+0x02) {
|
else if (type == 9 && key_size == 0x08+0x02) {
|
||||||
uint64_t file_keycode = get_u64be(keybuf+0x00);
|
uint64_t file_keycode = get_u64be(keybuf+0x00);
|
||||||
uint16_t file_subkey = get_u16be(keybuf+0x08);
|
uint16_t file_subkey = get_u16be(keybuf+0x08);
|
||||||
cri_key9_derive(file_keycode, file_subkey, xor_start, xor_mult, xor_add);
|
cri_key9_derive(file_keycode, file_subkey, xor_start, xor_mult, xor_add);
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* no key set or unknown format, try list */
|
/* no key set or unknown format, try list */
|
||||||
@ -525,5 +533,5 @@ static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint1
|
|||||||
done:
|
done:
|
||||||
free(scales);
|
free(scales);
|
||||||
free(prescales);
|
free(prescales);
|
||||||
return rc;
|
return rc != 0;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,7 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||||||
|
|
||||||
/* .aif: common (AIFF or AIFC)
|
/* .aif: common (AIFF or AIFC)
|
||||||
* .wav: SimCity 3000 (Mac) (both AIFF and AIFC)
|
* .wav: SimCity 3000 (Mac) (both AIFF and AIFC)
|
||||||
|
* .aiff: rare and actually AIFC (maybe renamed AIFF too) [Cro-Mag Rally (Mac)]
|
||||||
* (extensionless): Doom (3DO)
|
* (extensionless): Doom (3DO)
|
||||||
*
|
*
|
||||||
* .aifc: renamed AIFC?
|
* .aifc: renamed AIFC?
|
||||||
@ -97,20 +98,19 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||||||
* .xa: SimCity 3000 (Mac)
|
* .xa: SimCity 3000 (Mac)
|
||||||
* .caf: Topple (iOS)
|
* .caf: Topple (iOS)
|
||||||
*
|
*
|
||||||
* .aiff: renamed AIFF?
|
|
||||||
* .acm: Crusader - No Remorse (SAT)
|
* .acm: Crusader - No Remorse (SAT)
|
||||||
* .adp: Sonic Jam (SAT)
|
* .adp: Sonic Jam (SAT)
|
||||||
* .ai: Dragon Force (SAT)
|
* .ai: Dragon Force (SAT)
|
||||||
* .pcm: Road Rash (SAT)
|
* .pcm: Road Rash (SAT)
|
||||||
*/
|
*/
|
||||||
if (check_extensions(sf, "aif,laif,wav,lwav,")) {
|
if (check_extensions(sf, "aif,laif,wav,lwav,aiff,laiff,")) {
|
||||||
is_aifc_ext = 1;
|
is_aifc_ext = 1;
|
||||||
is_aiff_ext = 1;
|
is_aiff_ext = 1;
|
||||||
}
|
}
|
||||||
else if (check_extensions(sf, "aifc,laifc,afc,cbd2,bgm,fda,n64,xa,caf")) {
|
else if (check_extensions(sf, "aifc,laifc,afc,cbd2,bgm,fda,n64,xa,caf")) {
|
||||||
is_aifc_ext = 1;
|
is_aifc_ext = 1;
|
||||||
}
|
}
|
||||||
else if (check_extensions(sf, "aiff,laiff,acm,adp,ai,pcm")) {
|
else if (check_extensions(sf, "acm,adp,ai,pcm")) {
|
||||||
is_aiff_ext = 1;
|
is_aiff_ext = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -138,6 +138,8 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||||||
if (file_size != aifx_size + 0x08) {
|
if (file_size != aifx_size + 0x08) {
|
||||||
if (is_aiff && file_size == aifx_size + 0x08 + 0x08)
|
if (is_aiff && file_size == aifx_size + 0x08 + 0x08)
|
||||||
aifx_size += 0x08; /* [Psychic Force Puzzle Taisen CD2 (PS1)] */
|
aifx_size += 0x08; /* [Psychic Force Puzzle Taisen CD2 (PS1)] */
|
||||||
|
else if (is_aifc && file_size == aifx_size + 0x08 + 0x4c)
|
||||||
|
aifx_size += 0x4c; /* Cro-Mag Rally (Mac), only one file */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aifx_size + 0x08 != file_size) {
|
if (aifx_size + 0x08 != file_size) {
|
||||||
@ -145,7 +147,6 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* read through chunks to verify format and find metadata */
|
/* read through chunks to verify format and find metadata */
|
||||||
{
|
{
|
||||||
off_t offset = 0x0c; /* start with first chunk within FORM */
|
off_t offset = 0x0c; /* start with first chunk within FORM */
|
||||||
@ -164,7 +165,7 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
switch(chunk_type) {
|
switch(chunk_type) {
|
||||||
case 0x46564552: /* "FVER" (version info, required) */
|
case 0x46564552: /* "FVER" (version info, officially required but some odd game ommits it [Cro-Mag Rally (Mac)]) */
|
||||||
if (fver_found) goto fail;
|
if (fver_found) goto fail;
|
||||||
if (is_aiff) goto fail; /* plain AIFF shouldn't have */
|
if (is_aiff) goto fail; /* plain AIFF shouldn't have */
|
||||||
fver_found = 1;
|
fver_found = 1;
|
||||||
@ -315,14 +316,14 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_aifc) {
|
if (is_aifc) {
|
||||||
if (!fver_found || !comm_found || !data_found)
|
if (/*!fver_found ||*/ !comm_found || !data_found)
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (is_aiff) {
|
}
|
||||||
|
else if (is_aiff) {
|
||||||
if (!comm_found || !data_found)
|
if (!comm_found || !data_found)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* read loop points */
|
/* read loop points */
|
||||||
if (inst_offset && mark_offset) {
|
if (inst_offset && mark_offset) {
|
||||||
int start_marker;
|
int start_marker;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "../coding/hca_decoder_clhca.h"
|
#include "../coding/hca_decoder_clhca.h"
|
||||||
#include "../util/channel_mappings.h"
|
#include "../util/channel_mappings.h"
|
||||||
#include "../util/companion_files.h"
|
#include "../util/companion_files.h"
|
||||||
|
#include "../util/cri_keys.h"
|
||||||
|
|
||||||
#ifdef VGM_DEBUG_OUTPUT
|
#ifdef VGM_DEBUG_OUTPUT
|
||||||
//#define HCA_BRUTEFORCE
|
//#define HCA_BRUTEFORCE
|
||||||
@ -45,14 +46,21 @@ VGMSTREAM* init_vgmstream_hca_subkey(STREAMFILE* sf, uint16_t subkey) {
|
|||||||
/* find decryption key in external file or preloaded list */
|
/* find decryption key in external file or preloaded list */
|
||||||
if (hca_info->encryptionEnabled) {
|
if (hca_info->encryptionEnabled) {
|
||||||
uint64_t keycode = 0;
|
uint64_t keycode = 0;
|
||||||
uint8_t keybuf[0x08+0x02];
|
uint8_t keybuf[20+1] = {0}; /* max keystring 20, +1 extra null */
|
||||||
size_t keysize;
|
size_t key_size;
|
||||||
|
|
||||||
keysize = read_key_file(keybuf, sizeof(keybuf), sf);
|
key_size = read_key_file(keybuf, sizeof(keybuf) - 1, sf);
|
||||||
if (keysize == 0x08) { /* standard */
|
|
||||||
|
bool is_keystring = cri_key9_valid_keystring(keybuf, key_size);
|
||||||
|
|
||||||
|
if (is_keystring) { /* number */
|
||||||
|
const char* keystring = (const char*)keybuf;
|
||||||
|
keycode = strtoull(keystring, NULL, 10);
|
||||||
|
}
|
||||||
|
else if (key_size == 0x08) { /* hex */
|
||||||
keycode = get_u64be(keybuf+0x00);
|
keycode = get_u64be(keybuf+0x00);
|
||||||
}
|
}
|
||||||
else if (keysize == 0x08+0x02) { /* seed key + AWB subkey */
|
else if (key_size == 0x08+0x02) { /* seed key + AWB subkey */
|
||||||
keycode = get_u64be(keybuf+0x00);
|
keycode = get_u64be(keybuf+0x00);
|
||||||
subkey = get_u16be(keybuf+0x08);
|
subkey = get_u16be(keybuf+0x08);
|
||||||
}
|
}
|
||||||
|
@ -408,6 +408,23 @@ static int make_group_segment(txtp_header* txtp, txtp_group* grp, int position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* fix loop keep (do it before init'ing as loops/metadata may be disabled for segments) */
|
||||||
|
int32_t loop_start_sample = 0, loop_end_sample = 0;
|
||||||
|
if (loop_flag && txtp->is_loop_keep) {
|
||||||
|
int32_t current_samples = 0;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (loop_start == i+1 /*&& txtp->vgmstream[i + position]->loop_start_sample*/) {
|
||||||
|
loop_start_sample = current_samples + txtp->vgmstream[i + position]->loop_start_sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_samples += txtp->vgmstream[i + position]->num_samples;
|
||||||
|
|
||||||
|
if (loop_end == i+1 && txtp->vgmstream[i + position]->loop_end_sample) {
|
||||||
|
loop_end_sample = current_samples - txtp->vgmstream[i + position]->num_samples + txtp->vgmstream[i + position]->loop_end_sample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* init layout */
|
/* init layout */
|
||||||
data_s = init_layout_segmented(count);
|
data_s = init_layout_segmented(count);
|
||||||
if (!data_s) goto fail;
|
if (!data_s) goto fail;
|
||||||
@ -436,18 +453,8 @@ static int make_group_segment(txtp_header* txtp, txtp_group* grp, int position,
|
|||||||
|
|
||||||
/* fix loop keep */
|
/* fix loop keep */
|
||||||
if (loop_flag && txtp->is_loop_keep) {
|
if (loop_flag && txtp->is_loop_keep) {
|
||||||
int32_t current_samples = 0;
|
vgmstream->loop_start_sample = loop_start_sample;
|
||||||
for (i = 0; i < count; i++) {
|
vgmstream->loop_end_sample = loop_end_sample;
|
||||||
if (loop_start == i+1 /*&& data_s->segments[i]->loop_start_sample*/) {
|
|
||||||
vgmstream->loop_start_sample = current_samples + data_s->segments[i]->loop_start_sample;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_samples += data_s->segments[i]->num_samples;
|
|
||||||
|
|
||||||
if (loop_end == i+1 && data_s->segments[i]->loop_end_sample) {
|
|
||||||
vgmstream->loop_end_sample = current_samples - data_s->segments[i]->num_samples + data_s->segments[i]->loop_end_sample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,14 +126,28 @@ end:
|
|||||||
*p_key3 = key3;
|
*p_key3 = key3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cri_key8_valid_keystring(uint8_t* buf, int buf_size) {
|
bool cri_key8_valid_keystring(uint8_t* buf, int buf_size) {
|
||||||
int i;
|
if (buf_size <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
for (i = 0; i < buf_size; i++) {
|
for (int i = 0; i < buf_size; i++) {
|
||||||
if (buf[i] < 0x20 || buf[i] > 0x8f) { /* allow 0x8x for (uncommon) cases of SHIFT-JIS */
|
if (buf[i] < 0x20 || buf[i] > 0x8f) { /* allow 0x8x for (uncommon) cases of SHIFT-JIS */
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cri_key9_valid_keystring(uint8_t* buf, int buf_size) {
|
||||||
|
if (buf_size <= 0 || buf_size > 20) /* max u64 */
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < buf_size; i++) {
|
||||||
|
if (buf[i] < 0x30 || buf[i] > 0x39) { /* numbers only */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
#define _CRI_KEYS_H_
|
#define _CRI_KEYS_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
/* common CRI key helpers */
|
/* common CRI key helpers */
|
||||||
|
|
||||||
void cri_key8_derive(const char* key8, uint16_t* p_key1, uint16_t* p_key2, uint16_t* p_key3);
|
void cri_key8_derive(const char* key8, uint16_t* p_key1, uint16_t* p_key2, uint16_t* p_key3);
|
||||||
void cri_key9_derive(uint64_t key9, uint16_t subkey, uint16_t* p_key1, uint16_t* p_key2, uint16_t* p_key3);
|
void cri_key9_derive(uint64_t key9, uint16_t subkey, uint16_t* p_key1, uint16_t* p_key2, uint16_t* p_key3);
|
||||||
|
|
||||||
int cri_key8_valid_keystring(uint8_t* buf, int buf_size);
|
bool cri_key8_valid_keystring(uint8_t* buf, int buf_size);
|
||||||
|
bool cri_key9_valid_keystring(uint8_t* buf, int buf_size);
|
||||||
|
|
||||||
#endif /* _CRI_KEYS_H_ */
|
#endif /* _CRI_KEYS_H_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user