169 lines
3.7 KiB
C
169 lines
3.7 KiB
C
#include "../libraries/console/console_shim.h"
|
|
#include "../libraries/sha/sha1.h"
|
|
#include "../libraries/sha/sha256.h"
|
|
#include <kolibrios/app.h>
|
|
#include <kolibrios/syscall.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define KOS_PATH_MAX 1024
|
|
|
|
typedef struct
|
|
{
|
|
dword subfunction;
|
|
dword offset_low;
|
|
dword offset_high;
|
|
dword size;
|
|
void *buffer;
|
|
char path[KOS_PATH_MAX];
|
|
} kos_read_file_req_t;
|
|
|
|
static unsigned long
|
|
kos_read_file_syscall (const kos_read_file_req_t *req,
|
|
unsigned long *bytes_read)
|
|
{
|
|
unsigned long eax = SF_FILE;
|
|
unsigned long ebx = (unsigned long)req;
|
|
|
|
__asm__ __volatile__ ("int $0x40" : "+a"(eax), "+b"(ebx) : : "memory");
|
|
|
|
if (bytes_read != NULL)
|
|
{
|
|
*bytes_read = ebx;
|
|
}
|
|
|
|
return eax;
|
|
}
|
|
|
|
/* Read an entire file using SF_FILE/SSF_READ_FILE and return a heap buffer. */
|
|
static int
|
|
read_entire_file_syscall (const char *path, BYTE **out_buffer,
|
|
size_t *out_size)
|
|
{
|
|
BYTE *buffer;
|
|
size_t size = 0;
|
|
size_t capacity = 4096;
|
|
|
|
if (path == NULL || out_buffer == NULL || out_size == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
buffer = (BYTE *)malloc (capacity);
|
|
if (buffer == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
kos_read_file_req_t req;
|
|
unsigned long bytes_read = 0;
|
|
unsigned long status;
|
|
dword chunk_size;
|
|
|
|
if (size == capacity)
|
|
{
|
|
size_t new_capacity = capacity * 2;
|
|
BYTE *new_buffer = (BYTE *)realloc (buffer, new_capacity);
|
|
if (new_buffer == NULL)
|
|
{
|
|
free (buffer);
|
|
return -1;
|
|
}
|
|
buffer = new_buffer;
|
|
capacity = new_capacity;
|
|
}
|
|
|
|
chunk_size = (dword)(capacity - size);
|
|
if (chunk_size > 4096u)
|
|
{
|
|
chunk_size = 4096u;
|
|
}
|
|
|
|
req.subfunction = SSF_READ_FILE;
|
|
req.offset_low = (dword)size;
|
|
req.offset_high = 0;
|
|
req.size = chunk_size;
|
|
req.buffer = buffer + size;
|
|
req.path[0] = '\0';
|
|
strncat (req.path, path, KOS_PATH_MAX - 1);
|
|
|
|
status = kos_read_file_syscall (&req, &bytes_read);
|
|
size += (size_t)bytes_read;
|
|
|
|
if (status == 0)
|
|
{
|
|
if (bytes_read == 0)
|
|
{
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (status == 6)
|
|
{
|
|
break;
|
|
}
|
|
|
|
free (buffer);
|
|
return (int)status;
|
|
}
|
|
|
|
*out_buffer = buffer;
|
|
*out_size = size;
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
BYTE *file_buffer;
|
|
size_t bytes_read;
|
|
int read_status;
|
|
const char *program_path = __kosapp_name;
|
|
|
|
con_init ((dword)120, (dword)60, (dword)120, (dword)60, "Hash test");
|
|
con_printf ("Calculating SHA hashes of the file: %s\n", program_path);
|
|
|
|
read_status
|
|
= read_entire_file_syscall (program_path, &file_buffer, &bytes_read);
|
|
if (read_status != 0)
|
|
{
|
|
con_printf ("Failed to read file via syscall, error=%d\n", read_status);
|
|
con_exit (false);
|
|
return 1;
|
|
}
|
|
|
|
SHA1_CTX sha1_ctx;
|
|
BYTE sha1_hash[SHA1_BLOCK_SIZE];
|
|
sha1_init (&sha1_ctx);
|
|
sha1_update (&sha1_ctx, file_buffer, bytes_read);
|
|
sha1_final (&sha1_ctx, sha1_hash);
|
|
|
|
con_write_asciiz ("SHA1 hash of the program file:\n");
|
|
for (int i = 0; i < SHA1_BLOCK_SIZE; i++)
|
|
{
|
|
con_printf ("%02x", sha1_hash[i]);
|
|
}
|
|
con_write_asciiz ("\n");
|
|
|
|
SHA256_CTX sha256_ctx;
|
|
BYTE sha256_hash[SHA256_BLOCK_SIZE];
|
|
sha256_init (&sha256_ctx);
|
|
sha256_update (&sha256_ctx, file_buffer, bytes_read);
|
|
sha256_final (&sha256_ctx, sha256_hash);
|
|
free (file_buffer);
|
|
|
|
con_write_asciiz ("SHA256 hash of the program file:\n");
|
|
for (int i = 0; i < SHA256_BLOCK_SIZE; i++)
|
|
{
|
|
con_printf ("%02x", sha256_hash[i]);
|
|
}
|
|
con_write_asciiz ("\n");
|
|
|
|
free (file_buffer);
|
|
con_exit (false);
|
|
return 0;
|
|
}
|