TwlToolsRED/build/tools/TamperDetectorForSrl/card_hash.cpp
n1481 a438710879 digest1, digest2 の各テーブルを検証する機能の追加
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlToolsRED@567 7061adef-622a-194b-ae81-725974e89856
2011-07-06 09:15:02 +00:00

469 lines
17 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "types.h"
#include <string.h>
#include <openssl/hmac.h> /* libcrypto.a */
#include "twl_format_rom.h"
#include "card_hash.h"
#define MATH_SHA1_DIGEST_SIZE (160/8)
#define CARD_ROM_HASH_SIZE (20)
static u8 CARDiHmacKey[] =
{
0x21, 0x06, 0xc0, 0xde, 0xba, 0x98, 0xce, 0x3f,
0xa6, 0x92, 0xe3, 0x9d, 0x46, 0xf2, 0xed, 0x01,
0x76, 0xe3, 0xcc, 0x08, 0x56, 0x23, 0x63, 0xfa,
0xca, 0xd4, 0xec, 0xdf, 0x9a, 0x62, 0x78, 0x34,
0x8f, 0x6d, 0x63, 0x3c, 0xfe, 0x22, 0xca, 0x92,
0x20, 0x88, 0x97, 0x23, 0xd2, 0xcf, 0xae, 0xc2,
0x32, 0x67, 0x8d, 0xfe, 0xca, 0x83, 0x64, 0x98,
0xac, 0xfd, 0x3e, 0x37, 0x87, 0x46, 0x58, 0x24,
};
/*
unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
int key_len, const unsigned char *d, int n,
unsigned char *md, unsigned int *md_len);
*/
HMAC_CTX myHmacContext;
void MATH_CalcHMACSHA1(void *digest, const void *bin_ptr, u32 bin_len, const void *key_ptr, u32 key_len)
{
unsigned int res_len;
HMAC( EVP_sha1(),
key_ptr, key_len,
(const unsigned char*)bin_ptr, (size_t)bin_len,
(unsigned char*)digest, &res_len);
}
static bool CARDi_CompareHash(const void *hash, void *buffer, u32 length)
{
bool ret = true;
u8 tmphash[CARD_ROM_HASH_SIZE];
MATH_CalcHMACSHA1(tmphash, buffer, length, CARDiHmacKey, sizeof(CARDiHmacKey));
if (memcmp(hash, tmphash, sizeof(tmphash)) != 0)
{
ret = false;
printf("ROM-hash comparation error!\n");
}
else
{
// printf("ROM-hash comparation success.\n");
}
/*
u8* myhash = (u8*)hash;
printf( "digest2:0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
myhash[0], myhash[1], myhash[2], myhash[3], myhash[4], myhash[5],
myhash[6], myhash[7], myhash[8], myhash[9], myhash[10], myhash[11],
myhash[12], myhash[13], myhash[14], myhash[15], myhash[16], myhash[17],
myhash[18], myhash[19]);
printf( "tmphash:0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
tmphash[0], tmphash[1], tmphash[2], tmphash[3], tmphash[4], tmphash[5],
tmphash[6], tmphash[7], tmphash[8], tmphash[9], tmphash[10], tmphash[11],
tmphash[12], tmphash[13], tmphash[14], tmphash[15], tmphash[16], tmphash[17],
tmphash[18], tmphash[19]);
*/
return ret;
}
void CARDi_Init( CARDRomHashContext *context, RomHeader* header)
{
context->bytes_per_sector = header->digest1_block_size;
context->sectors_per_block = header->digest2_covered_digest1_num;
context->area_ntr.offset = header->nitro_digest_area_rom_offset;
context->area_ntr.length = header->nitro_digest_area_size;
context->area_ltd.offset = header->twl_digest_area_rom_offset;
context->area_ltd.length = header->twl_digest_area_size;
context->sector_hash.offset = header->digest1_table_offset;
context->sector_hash.length = header->digest1_table_size;
context->block_hash.offset = header->digest2_table_offset;
context->block_hash.length = header->digest2_table_size;
context->block_max = CARD_ROM_HASH_BLOCK_MAX;
context->sector_max = CARD_ROM_HASH_SECTOR_MAX;
// digest2
context->master_hash = (u8*)malloc( (1024*1024*1024/8) /
(header->digest1_block_size * header->digest2_covered_digest1_num) *
CARD_ROM_HASH_SIZE);
// digest1
context->hash = (u8*)malloc( header->digest2_covered_digest1_num * CARD_ROM_HASH_SIZE);
// rom image
context->buffer = (u8*)malloc( header->digest1_block_size);
// rom size
{
int i;
u32 rom_size;
for( i=0; i<header->rom_size; i++)
{
rom_size *= 2;
}
context->rom_size = (rom_size * 1024 / 8 * 1024);
}
}
/*---------------------------------------------------------------------------*
Name: CARDi_GetHashSectorIndex
Description: <20>w<EFBFBD><77><EFBFBD><EFBFBD>ROM<4F>I<EFBFBD>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD>N<EFBFBD>^<5E>ԍ<EFBFBD><D48D><EFBFBD><EFBFBD><EFBFBD>B
Arguments: context : CARDRomHashContext<78>\<5C><><EFBFBD><EFBFBD>
offset : ROM<4F>I<EFBFBD>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g
Returns: <20>w<EFBFBD><77><EFBFBD><EFBFBD>ROM<4F>I<EFBFBD>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD>N<EFBFBD>^<5E>ԍ<EFBFBD><D48D>B
*---------------------------------------------------------------------------*/
u32 CARDi_GetHashSectorIndex(const CARDRomHashContext *context, u32 offset)
{
offset -= context->area_ntr.offset;
if (offset >= context->area_ntr.length)
{
offset += (context->area_ntr.offset - context->area_ltd.offset);
if (offset < context->area_ltd.length)
{
offset += context->area_ntr.length;
}
else
{
printf("specified ROM address is outof-range.(unsafe without secure hash)\n");
exit(1);
}
}
return offset / context->bytes_per_sector;
}
//static CARDRomHashBlock* CARDi_TouchRomHashBlock(CARDRomHashContext *context, u32 sector)
//{
//}
void CARDi_CheckHash(CARDRomHashContext *context, FILE* fp, u32 start, u32 size, RomHeader* header)
{
long nowfp;
u32 offset;
int linear_rom_sector;
u32 i, j;
nowfp = ftell( fp);
for( j=0; j<(size/(context->bytes_per_sector * context->sectors_per_block)); j++)
{
for( i=0; i<context->sectors_per_block; i++)
{
offset = start +
(i * context->bytes_per_sector) +
(j * (context->sectors_per_block * context->bytes_per_sector));
printf( "%s, %d (offset:0x%lx), 0x%lx, 0x%lx, %ld, %ld\n", __FUNCTION__, __LINE__, offset, context->bytes_per_sector, context->sectors_per_block, i, j);
/* ROM<4F>f<EFBFBD>[<5B>^<5E><><EFBFBD>ǂ<EFBFBD> */
fseek( fp, offset, SEEK_SET);
fread( context->buffer, context->bytes_per_sector, 1, fp);
/* Digest1<74><31><EFBFBD>ǂ<EFBFBD> */
linear_rom_sector = CARDi_GetHashSectorIndex( context, offset);
fseek( fp, (header->digest1_table_offset + (linear_rom_sector * CARD_ROM_HASH_SIZE)), SEEK_SET);
fread( &(context->hash[i * CARD_ROM_HASH_SIZE]), CARD_ROM_HASH_SIZE, 1, fp);
printf( "-----digest1 check-----\n");
printf( "i = %ld, linear = %d\n", i, linear_rom_sector);
/* ROM<4F>f<EFBFBD>[<5B>^<5E><>Hash<73><68>Digest1<74>Ɣ<EFBFBD><C694>r */
CARDi_CompareHash( &(context->hash[i * CARD_ROM_HASH_SIZE]),
context->buffer, context->bytes_per_sector);
printf( "-----------------------\n");
}
}
fseek( fp, nowfp, SEEK_SET);
}
bool Digest1Check(CARDRomHashContext *context, FILE* fp, RomHeader* header, u32 start_offset, u32 size)
{
int digest1_index;
u32 offset, rest;
bool ret = true;
rest = size;
offset = start_offset;
do {
if( !(((start_offset >= header->aes_target_rom_offset)&&
(start_offset <= (header->aes_target_rom_offset + header->aes_target_size))) ||
(((start_offset + size) >= header->aes_target_rom_offset)&&
((start_offset + size) <= (header->aes_target_rom_offset + header->aes_target_size)))))
{
/* ROM<4F>f<EFBFBD>[<5B>^<5E><><EFBFBD>ǂ<EFBFBD> */
fseek( fp, offset, SEEK_SET);
fread( context->buffer, context->bytes_per_sector, 1, fp);
/* Digest1<74><31><EFBFBD>ǂ<EFBFBD> */
digest1_index = CARDi_GetHashSectorIndex( context, offset);
fseek( fp, (header->digest1_table_offset + (digest1_index * CARD_ROM_HASH_SIZE)), SEEK_SET);
fread( context->hash, CARD_ROM_HASH_SIZE, 1, fp);
/* ROM<4F>f<EFBFBD>[<5B>^<5E><>Hash<73><68>Digest1<74>Ɣ<EFBFBD><C694>r */
if( !CARDi_CompareHash( context->hash, context->buffer, context->bytes_per_sector))
{
ret = false;
}
}
rest -= context->bytes_per_sector;
offset += context->bytes_per_sector;
}
while( rest);
return ret;
}
bool Digest2Check(CARDRomHashContext *context, FILE* fp, RomHeader* header)
{
bool ret = true;
int i, j;
int digest1_index_num = (header->digest1_table_size / header->digest1_block_size);
for( i=0; i<digest1_index_num; )
{
for( j=0; j<(int)(header->digest2_covered_digest1_num); j++)
{
fseek( fp, (header->digest1_table_offset + ((i+j) * CARD_ROM_HASH_SIZE)), SEEK_SET);
fread( &(context->hash[j * CARD_ROM_HASH_SIZE]), CARD_ROM_HASH_SIZE, 1, fp);
}
/* Digest1<74><31>Digest2<74>Ɣ<EFBFBD><C694>r */
if( !CARDi_CompareHash( &(context->master_hash[(i/context->sectors_per_block) * CARD_ROM_HASH_SIZE]),
context->hash, (CARD_ROM_HASH_SIZE * context->sectors_per_block)))
{
ret = false;
}
i+= header->digest2_covered_digest1_num;
}
return ret;
}
void CARD_CheckHash(CARDRomHashContext *context, RomHeader* header, FILE* fp)
{
long nowfp;
nowfp = ftell( fp);
fseek( fp, header->digest2_table_offset, SEEK_SET);
fread( context->master_hash, header->digest2_table_size, 1, fp);
fseek( fp, nowfp, SEEK_SET);
printf( "\n");
printf( "nitro digest area check\n");
printf( "-----------------------\n");
// NITRO<52>_<EFBFBD>C<EFBFBD>W<EFBFBD>F<EFBFBD>X<EFBFBD>g<EFBFBD>G<EFBFBD><47><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD>
if( Digest1Check( context, fp, header, header->nitro_digest_area_rom_offset, header->nitro_digest_area_size))
{
printf( "<EFBFBD>i<EFBFBD><EFBFBD><EFBFBD><EFBFBD>OK.<2E>j\n");
}
printf( "-----------------------\n\n");
printf( "twl digest area check\n");
printf( "-----------------------\n");
// TWL<57>_<EFBFBD>C<EFBFBD>W<EFBFBD>F<EFBFBD>X<EFBFBD>g<EFBFBD>G<EFBFBD><47><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD>
if( Digest1Check( context, fp, header, header->twl_digest_area_rom_offset, header->twl_digest_area_size))
{
printf( "<EFBFBD>i<EFBFBD><EFBFBD><EFBFBD><EFBFBD>OK.<2E>j\n");
}
printf( "-----------------------\n\n");
printf( "digest2 check\n");
printf( "-----------------------\n");
if( Digest2Check( context, fp, header))
{
printf( "<EFBFBD>i<EFBFBD><EFBFBD><EFBFBD><EFBFBD>OK.<2E>j\n");
}
printf( "-----------------------\n\n");
}
/*
static void CARDi_ReadRomHashImageDirect(CARDRomHashContext *context, void *buffer, u32 offset, u32 length)
{
const u32 sectunit = context->bytes_per_sector;
const u32 blckunit = context->sectors_per_block;
u32 position = offset;
u32 end = length + offset;
u32 sector = CARDi_GetHashSectorIndex(context, position);
long nowgfp;
FILE* gfp;
while (position < end)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>”\<5C>ȍŏ<C88D><C58F>P<EFBFBD>ʂ̃C<CC83><43><EFBFBD>[<5B>W<EFBFBD>𓯊<EFBFBD><F093AF8A>ǂݍ<C782><DD8D>݁B
nowgfp = ftell( gfp);
fseek( gfp, position, SEEK_SET);
u32 available = fread( buffer, end - position, 1, gfp);
// <20><><EFBFBD><EFBFBD><EFBFBD>̌<EFBFBD><CC8C>ؒ<EFBFBD><D892>ɕK<C995>v<EFBFBD>ƂȂ肻<C882><E882BB><EFBFBD>ȃu<C883><75><EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD>ăA<C483>N<EFBFBD>Z<EFBFBD>X<EFBFBD>B
// (void)CARDi_TouchRomHashBlock(context, sector);
// <20><EFBFBD><E693BE><EFBFBD><EFBFBD><EFBFBD>C<EFBFBD><43><EFBFBD>[<5B>W<EFBFBD>̐<EFBFBD><CC90><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>؁B
while (available >= sectunit)
{
CARDRomHashBlock *block = CARDi_TouchRomHashBlock(context, sector);
u32 slot = sector - block->index * blckunit;
while ((slot < blckunit) && (available >= sectunit))
{
// <20>K<EFBFBD>v<EFBFBD>Ȃ炱<C882><E782B1><EFBFBD>Ńu<C583><75><EFBFBD>b<EFBFBD>N<EFBFBD>P<EFBFBD>ʂ̃n<CC83>b<EFBFBD>V<EFBFBD><56><EFBFBD>e<EFBFBD>[<5B>u<EFBFBD><75><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>؁B
if (block != context->valid_block)
{
OSIntrMode bak_cpsr = OS_DisableInterrupts();
while (context->loading_block)
{
OS_SleepThread(NULL);
}
if (block == context->loaded_block)
{
context->loaded_block = block->next;
}
(void)OS_RestoreInterrupts(bak_cpsr);
CARDi_CompareHash(&context->master_hash[block->index * CARD_ROM_HASH_SIZE],
block->hash, CARD_ROM_HASH_SIZE * blckunit);
block->next = context->valid_block;
context->valid_block = block;
}
// <20>C<EFBFBD><43><EFBFBD>[<5B>W<EFBFBD>̃n<CC83>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD>Z<EFBFBD>B
CARDi_CompareHash(&block->hash[slot * CARD_ROM_HASH_SIZE], buffer, sectunit);
position += sectunit;
available -= sectunit;
buffer = ((u8 *)buffer) + sectunit;
slot += 1;
sector += 1;
}
}
}
}
*/
#if 0
/*---------------------------------------------------------------------------*
Name: CARDi_ReadRomHashImageDirect
Description: <20>n<EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD>R<EFBFBD><52><EFBFBD>e<EFBFBD>L<EFBFBD>X<EFBFBD>g<EFBFBD>փL<D683><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɓ]<5D><><EFBFBD><EFBFBD><EFBFBD>֒<EFBFBD><D692>ڃR<DA83>s<EFBFBD>[<5B>B
Arguments: context : CARDRomHashContext<78>\<5C><><EFBFBD>́B
buffer : <20>]<5D><><EFBFBD><EFBFBD><EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40>B(4<>o<EFBFBD>C<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>K<EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
offset : <20>A<EFBFBD>N<EFBFBD>Z<EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD>ROM<4F>I<EFBFBD>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD>B
length : <20>]<5D><><EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD>B
Returns: None.
*---------------------------------------------------------------------------*/
static void CARDi_ReadRomHashImageDirect(CARDRomHashContext *context, void *buffer, u32 offset, u32 length)
{
const u32 sectunit = context->bytes_per_sector;
const u32 blckunit = context->sectors_per_block;
u32 position = offset;
u32 end = length + offset;
u32 sector = CARDi_GetHashSectorIndex(context, position);
while (position < end)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>”\<5C>ȍŏ<C88D><C58F>P<EFBFBD>ʂ̃C<CC83><43><EFBFBD>[<5B>W<EFBFBD>𓯊<EFBFBD><F093AF8A>ǂݍ<C782><DD8D>݁B
u32 available = (u32)(*context->ReadSync)(context->userdata, buffer, position, end - position);
// <20><><EFBFBD><EFBFBD><EFBFBD>̌<EFBFBD><CC8C>ؒ<EFBFBD><D892>ɕK<C995>v<EFBFBD>ƂȂ肻<C882><E882BB><EFBFBD>ȃu<C883><75><EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD>ăA<C483>N<EFBFBD>Z<EFBFBD>X<EFBFBD>B
(void)CARDi_TouchRomHashBlock(context, sector);
// <20><><EFBFBD><EFBFBD><EFBFBD>ɕK<C995>v<EFBFBD>ƂȂ镪<C882>̓ǂݍ<C782><DD8D>ݏ<EFBFBD><DD8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD><76><EFBFBD>B
if (context->ReadAsync && (position + available < end))
{
(void)(*context->ReadAsync)(context->userdata, NULL, position + available, end - (position + available));
}
// <20><EFBFBD><E693BE><EFBFBD><EFBFBD><EFBFBD>C<EFBFBD><43><EFBFBD>[<5B>W<EFBFBD>̐<EFBFBD><CC90><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>؁B
while (available >= sectunit)
{
CARDRomHashBlock *block = CARDi_TouchRomHashBlock(context, sector);
u32 slot = sector - block->index * blckunit;
while ((slot < blckunit) && (available >= sectunit))
{
// <20>K<EFBFBD>v<EFBFBD>Ȃ炱<C882><E782B1><EFBFBD>Ńu<C583><75><EFBFBD>b<EFBFBD>N<EFBFBD>P<EFBFBD>ʂ̃n<CC83>b<EFBFBD>V<EFBFBD><56><EFBFBD>e<EFBFBD>[<5B>u<EFBFBD><75><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>؁B
if (block != context->valid_block)
{
OSIntrMode bak_cpsr = OS_DisableInterrupts();
while (context->loading_block)
{
OS_SleepThread(NULL);
}
if (block == context->loaded_block)
{
context->loaded_block = block->next;
}
(void)OS_RestoreInterrupts(bak_cpsr);
CARDi_CompareHash(&context->master_hash[block->index * CARD_ROM_HASH_SIZE],
block->hash, CARD_ROM_HASH_SIZE * blckunit);
block->next = context->valid_block;
context->valid_block = block;
}
// <20>C<EFBFBD><43><EFBFBD>[<5B>W<EFBFBD>̃n<CC83>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD>Z<EFBFBD>B
CARDi_CompareHash(&block->hash[slot * CARD_ROM_HASH_SIZE], buffer, sectunit);
position += sectunit;
available -= sectunit;
buffer = ((u8 *)buffer) + sectunit;
slot += 1;
sector += 1;
}
}
}
}
/*---------------------------------------------------------------------------*
Name: MATH_CalcHMACSHA1
Description: HMAC-SHA-1 <20><><EFBFBD>v<EFBFBD>Z<EFBFBD><5A><EFBFBD><EFBFBD><EFBFBD>B
Arguments: digest HMAC-SHA-1 <20>l<EFBFBD><6C><EFBFBD>i<EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ւ̃|<7C>C<EFBFBD><43><EFBFBD>^
data <20><><EFBFBD>̓f<CD83>[<5B>^<5E>̃|<7C>C<EFBFBD><43><EFBFBD>^
dataLength <20><><EFBFBD>̓f<CD83>[<5B>^<5E><>
key <20><><EFBFBD>̃|<7C>C<EFBFBD><43><EFBFBD>^
keyLength <20><><EFBFBD>̒<EFBFBD><CC92><EFBFBD>
Returns: None.
*---------------------------------------------------------------------------*/
void MATH_CalcHMACSHA1(void *digest, const void *bin_ptr, u32 bin_len, const void *key_ptr, u32 key_len)
{
MATHSHA1Context context;
unsigned char hash_buf[ MATH_SHA1_DIGEST_SIZE ]; /* <20>n<EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD>֐<EFBFBD><D690><EFBFBD><EFBFBD><EFBFBD><E793BE><EFBFBD>n<EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD>l */
MATHiHMACFuncs hash2funcs = {
MATH_SHA1_DIGEST_SIZE,
(512/8),
};
hash2funcs.context = &context;
hash2funcs.hash_buf = hash_buf;
hash2funcs.HashReset = (void (*)(void*)) MATH_SHA1Init;
hash2funcs.HashSetSource = (void (*)(void*, const void*, u32)) MATH_SHA1Update;
hash2funcs.HashGetDigest = (void (*)(void*, void*)) MATH_SHA1GetHash;
MATHi_CalcHMAC(digest, bin_ptr, bin_len, key_ptr, key_len, &hash2funcs);
}
/*---------------------------------------------------------------------------*
Name: CARDi_CompareHash
Description: <20>n<EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD>ɂ<EFBFBD><C982><EFBFBD><E990B3><EFBFBD><EFBFBD><EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N<EFBFBD>B(HMAC-SHA1)
Arguments: hash : <20><><EFBFBD>r<EFBFBD><EFBFBD>ƂȂ<C682><C882>n<EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD>l
src : <20>`<60>F<EFBFBD>b<EFBFBD>N<EFBFBD>Ώۂ̃C<CC83><43><EFBFBD>[<5B>W
len<65>@: <20>`<60>F<EFBFBD>b<EFBFBD>N<EFBFBD>Ώۂ̃T<CC83>C<EFBFBD>Y
Returns: None.
*---------------------------------------------------------------------------*/
static void CARDi_CompareHash(const void *hash, void *buffer, u32 length)
{
u8 tmphash[CARD_ROM_HASH_SIZE];
MATH_CalcHMACSHA1(tmphash, buffer, length, CARDiHmacKey, sizeof(CARDiHmacKey));
if (MI_CpuComp8(hash, tmphash, sizeof(tmphash)) != 0)
{
printf("ROM-hash comparation error!\n");
}
}
#endif