Now using static buffers (and protecting with a semaphore) for kernel secprintf.
We have to do this because we need secure output in kmalloc.
This commit is contained in:
		| @@ -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]) | ||||
| @@ -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) | ||||
| { | ||||
|   | ||||
| @@ -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> | ||||
| @@ -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 | ||||
|  | ||||
| static char temp_buffer[BUFFER_SIZE]; | ||||
|  | ||||
| #ifndef _KERNEL | ||||
| static char temp_buffer[BUFFER_SIZE]; | ||||
| 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 | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -106,19 +108,29 @@ 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); | ||||
| @@ -126,11 +138,27 @@ secprintf(const char * secret, const char * msg, const char * name) | ||||
| 	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 | ||||
|   | ||||
| @@ -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_ */ | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
| @@ -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"); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user