2016-03-02 20:01:13 +01:00
|
|
|
#include "sha.h"
|
2019-04-17 00:08:43 +02:00
|
|
|
#include "mmio.h"
|
2016-03-02 20:01:13 +01:00
|
|
|
|
2019-03-14 15:33:39 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2020-01-23 00:59:32 +00:00
|
|
|
u32 data[16];
|
2019-03-14 15:33:39 +00:00
|
|
|
} _sha_block;
|
|
|
|
|
2016-03-02 20:01:13 +01:00
|
|
|
void sha_init(u32 mode)
|
|
|
|
{
|
|
|
|
while(*REG_SHACNT & 1);
|
|
|
|
*REG_SHACNT = mode | SHA_CNT_OUTPUT_ENDIAN | SHA_NORMAL_ROUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sha_update(const void* src, u32 size)
|
|
|
|
{
|
|
|
|
const u32* src32 = (const u32*)src;
|
|
|
|
|
|
|
|
while(size >= 0x40) {
|
|
|
|
while(*REG_SHACNT & 1);
|
2019-03-19 00:20:10 +01:00
|
|
|
*((volatile _sha_block*)REG_SHAINFIFO) = *((const _sha_block*)src32);
|
2018-03-14 00:00:57 +01:00
|
|
|
src32 += 16;
|
2016-03-02 20:01:13 +01:00
|
|
|
size -= 0x40;
|
|
|
|
}
|
|
|
|
while(*REG_SHACNT & 1);
|
2019-04-17 00:08:43 +02:00
|
|
|
if(size) iomemcpy((void*)REG_SHAINFIFO, src32, size);
|
2016-03-02 20:01:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void sha_get(void* res) {
|
2017-08-04 02:06:42 +02:00
|
|
|
u32 hash_size = (*REG_SHACNT&SHA224_MODE) ? (224/8) :
|
|
|
|
(*REG_SHACNT&SHA1_MODE) ? (160/8) : (256/8);
|
2016-03-02 20:01:13 +01:00
|
|
|
*REG_SHACNT = (*REG_SHACNT & ~SHA_NORMAL_ROUND) | SHA_FINAL_ROUND;
|
|
|
|
while(*REG_SHACNT & SHA_FINAL_ROUND);
|
|
|
|
while(*REG_SHACNT & 1);
|
2019-04-17 00:08:43 +02:00
|
|
|
if (hash_size) iomemcpy(res, (void*)REG_SHAHASH, hash_size);
|
2016-03-02 20:01:13 +01:00
|
|
|
}
|
2016-04-28 22:54:31 +02:00
|
|
|
|
|
|
|
void sha_quick(void* res, const void* src, u32 size, u32 mode) {
|
|
|
|
sha_init(mode);
|
|
|
|
sha_update(src, size);
|
|
|
|
sha_get(res);
|
|
|
|
}
|
2017-02-03 02:21:16 +01:00
|
|
|
|
|
|
|
int sha_cmp(const void* sha, const void* src, u32 size, u32 mode) {
|
|
|
|
u8 res[0x20];
|
|
|
|
sha_quick(res, src, size, mode);
|
|
|
|
return memcmp(sha, res, 0x20);
|
|
|
|
}
|