Skip to content

Commit

Permalink
Now using static buffers (and protecting with a semaphore) for kernel…
Browse files Browse the repository at this point in the history
… secprintf.

We have to do this because we need secure output in kmalloc.
  • Loading branch information
shaseley committed Mar 7, 2016
1 parent 2cb47cb commit 196bb3b
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 28 deletions.
15 changes: 3 additions & 12 deletions common/libtest161/secure.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,35 +44,25 @@ static int did_random = 0;
#define MSEC_PER_SEC 1000ULL
#endif

// Both userspace and the kernel are using the temp buffers now.
static void * _alloc(size_t size)
{
#ifdef _KERNEL
// Compiler
(void)temp_buffers;
(void)buf_num;

return kmalloc(size);
#else
(void)size;
void *ptr = temp_buffers[buf_num];
buf_num++;
buf_num = buf_num % NUM_BUFFERS;
return ptr;
#endif
}

static void _free(void *ptr)
{
#ifdef _KERNEL
kfree(ptr);
#else
(void)ptr;
#endif
}

/*
* hamc_sha256 follows FIPS 198-1 HMAC using sha256.
* See http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf for details.
* NOTE: This is only thread-safe if called from within secprintf()!!!
*/
static int hmac_sha256(const char *msg, size_t msg_len, const char *key, size_t key_len,
unsigned char output[SHA256_OUTPUT_SIZE])
Expand Down Expand Up @@ -189,6 +179,7 @@ int hmac(const char *msg, size_t msg_len, const char *key, size_t key_len,
return 0;
}

// NOTE: This is only thread-safe if called from within secprintf()!!!
int hmac_salted(const char *msg, size_t msg_len, const char *key, size_t key_len,
char **hash_str, char **salt_str)
{
Expand Down
60 changes: 44 additions & 16 deletions common/libtest161/test161.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#ifdef _KERNEL
#include <types.h>
#include <lib.h>
#include <synch.h>
#include <kern/errno.h>
#include <kern/secure.h>
#include <kern/test161.h>
Expand All @@ -17,31 +18,32 @@
#include <test161/secure.h>
#endif

// Hack for allocating userspace memory without malloc.
#define BUFFER_SIZE 4096
// Hack for allocating userspace memory without malloc, and for
// allowing secprintf in kmalloc when we're out of memory.
#define BUFFER_SIZE 1024

#ifndef _KERNEL
static char temp_buffer[BUFFER_SIZE];

#ifndef _KERNEL
static char write_buffer[BUFFER_SIZE];
#endif

static inline void * _alloc(size_t size)
{
#ifdef _KERNEL
return kmalloc(size);
#else
(void)size;
return temp_buffer;
// secprintf needs to be synchronized in the kernel because multiple threads
// may be trying to secprintf at the same time.
static struct semaphore *test161_sem;
#endif

// For now, allocating just passes a reference to our static temp buffer, and
// free does nothing.
static inline void * _alloc()
{
return temp_buffer;
}

static inline void _free(void *ptr)
{
#ifdef _KERNEL
kfree(ptr);
#else
(void)ptr;
#endif
}

/*
Expand Down Expand Up @@ -106,31 +108,57 @@ secprintf(const char * secret, const char * msg, const char * name)
int res;
size_t len;

#ifdef _KERNEL
if (test161_sem == NULL) {
panic("test161_sem is NULL. Your kernel is missing test161_bootstrap.");
}
P(test161_sem);
#endif

hash = salt = fullmsg = NULL;

// test161 expects "name: msg"
len = strlen(name) + strlen(msg) + 3; // +3 for " :" and null terminator
fullmsg = (char *)_alloc(len);
if (fullmsg == NULL) {
return -ENOMEM;
res = -ENOMEM;
goto out;
}
snprintf(fullmsg, len, "%s: %s", name, msg);

res = hmac_salted(fullmsg, len-1, secret, strlen(secret), &hash, &salt);
if (res)
return -res;
if (res) {
res = -res;
goto out;
}

#ifdef _KERNEL
res = kprintf("(%s, %s, %s, %s: %s)\n", name, hash, salt, name, msg);
#else
res = say("(%s, %s, %s, %s: %s)\n", name, hash, salt, name, msg);
#endif

out:
// These may be NULL, but that's OK
_free(hash);
_free(salt);
_free(fullmsg);

#ifdef _KERNEL
V(test161_sem);
#endif

return res;
}

#endif

#ifdef _KERNEL
void test161_bootstrap()
{
test161_sem = sem_create("test161", 1);
if (test161_sem == NULL) {
panic("Failed to create test161 secprintf semaphore");
}
}
#endif
4 changes: 4 additions & 0 deletions kern/include/kern/test161.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ int success(int, const char *, const char *);
int secprintf(const char *secret, const char *msg, const char *name);
int partial_credit(const char *secret, const char *name, int scored, int total);

#ifdef _KERNEL
void test161_bootstrap(void);
#endif

#endif /* _KERN_TEST161_H_ */
2 changes: 2 additions & 0 deletions kern/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <device.h>
#include <syscall.h>
#include <test.h>
#include <kern/test161.h>
#include <version.h>
#include "autoconf.h" // for pseudoconfig

Expand Down Expand Up @@ -127,6 +128,7 @@ boot(void)
vm_bootstrap();
kprintf_bootstrap();
thread_start_cpus();
test161_bootstrap();

/* Default bootfs - but ignore failure, in case emu0 doesn't exist */
vfs_setbootfs("emu0");
Expand Down

0 comments on commit 196bb3b

Please sign in to comment.