Files

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;
}