diff --git a/common/libc/secure/secure.h b/common/libc/secure/secure.h deleted file mode 100644 index 1568d67..0000000 --- a/common/libc/secure/secure.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _SECURE_H -#define _SECURE_H - -#define SHA256_BLOCK_SIZE 64 -#define SHA256_OUTPUT_SIZE 32 - -#define TOHEX(n) n < 10 ? '0'+n : 'a' + (n-10) - -// Compute the hex string from SHA256 hash output -void hex_from_hash(unsigned char hash[SHA256_OUTPUT_SIZE], char res[SHA256_OUTPUT_SIZE*2 + 1]); - -// Compute the FIPS 198-1 complient HMAC of msg using SHA256 -void hmac_sha256(const char *msg, size_t msg_len, char *key, size_t key_len, - unsigned char output[SHA256_OUTPUT_SIZE]); - -#endif //_SECURE_H diff --git a/common/libc/secure/config.h b/common/libtest161/config.h similarity index 100% rename from common/libc/secure/config.h rename to common/libtest161/config.h diff --git a/common/libc/secure/secure.c b/common/libtest161/secure.c similarity index 90% rename from common/libc/secure/secure.c rename to common/libtest161/secure.c index 4936b05..1aabe7d 100644 --- a/common/libc/secure/secure.c +++ b/common/libtest161/secure.c @@ -27,12 +27,28 @@ static const unsigned char ipad[SHA256_BLOCK_SIZE] = { [0 ... SHA256_BLOCK_SIZE-1] = 0x36 }; static const unsigned char opad[SHA256_BLOCK_SIZE] = { [0 ... SHA256_BLOCK_SIZE-1] = 0x5c }; +// Hack for not having a userspace malloc until ASST3. We 'allocate' these statuc buffers. +// This works because the process single-threaded. +#define NUM_BUFFERS 4 +#define BUFFER_LEN 1024 + +static char temp_buffers[NUM_BUFFERS][BUFFER_LEN]; +static int buf_num = 0; + static void * _alloc(size_t size) { #ifdef _KERNEL + // Compiler + (void)temp_buffers; + (void)buf_num; + return kmalloc(size); #else - return malloc(size); + (void)size; + void *ptr = temp_buffers[buf_num]; + buf_num++; + buf_num = buf_num % NUM_BUFFERS; + return ptr; #endif } @@ -41,7 +57,7 @@ static void _free(void *ptr) #ifdef _KERNEL kfree(ptr); #else - free(ptr); + (void)ptr; #endif } diff --git a/common/libc/secure/sha256.c b/common/libtest161/sha256.c similarity index 100% rename from common/libc/secure/sha256.c rename to common/libtest161/sha256.c diff --git a/common/libc/secure/sha256.h b/common/libtest161/sha256.h similarity index 100% rename from common/libc/secure/sha256.h rename to common/libtest161/sha256.h diff --git a/common/libtest161/test161.c b/common/libtest161/test161.c new file mode 100644 index 0000000..c1b2ba3 --- /dev/null +++ b/common/libtest161/test161.c @@ -0,0 +1,107 @@ +// Beware, this code is shared between the kernel and userspace. + +#ifdef _KERNEL +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#endif + +// Hack for allocating userspace memory without malloc. +static char temp_buffer[4096]; + +static inline void * _alloc(size_t size) +{ +#ifdef _KERNEL + (void)temp_buffer; + return kmalloc(size); +#else + (void)size; + return temp_buffer; +#endif +} + +static inline void _free(void *ptr) +{ +#ifdef _KERNEL + kfree(ptr); +#else + (void)ptr; +#endif +} + +/* + * Common success function for kernel tests. If SECRET_TESTING is defined, + * ksecprintf will compute the hmac/sha256 hash of any message using the + * shared secret and a random salt value. The (secure) server also knows + * the secret and can verify the message was generated by a trusted source. + * The salt value prevents against replay attacks. + */ +int +success(int status, const char * secret, const char * name) { + if (status == TEST161_SUCCESS) { + return secprintf(secret, "SUCCESS", name); + } else { + return secprintf(secret, "FAIL", name); + } +} + +#ifndef SECRET_TESTING + +int +secprintf(const char * secret, const char * msg, const char * name) +{ + (void)secret; + +#ifdef _KERNEL + return kprintf("%s: %s\n", name, msg); +#else + return printf("%s: %s\n", name, msg); +#endif +} + +#else + +int +secprintf(const char * secret, const char * msg, const char * name) +{ + char *hash, *salt, *fullmsg; + int res; + size_t len; + + 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; + } + snprintf(fullmsg, len, "%s: %s", name, msg); + + res = hmac_salted(fullmsg, len-1, secret, strlen(secret), &hash, &salt); + if (res) + return -res; + +#ifdef _KERNEL + res = kprintf("(%s, %s, %s, %s: %s)\n", name, hash, salt, name, msg); +#else + res = printf("(%s, %s, %s, %s: %s)\n", name, hash, salt, name, msg); +#endif + + _free(hash); + _free(salt); + _free(fullmsg); + + return res; +} + +#endif diff --git a/kern/conf/conf.kern b/kern/conf/conf.kern index 61f1b1d..5e5f927 100644 --- a/kern/conf/conf.kern +++ b/kern/conf/conf.kern @@ -310,12 +310,12 @@ file ../common/libc/string/strrchr.c file ../common/libc/string/strtok_r.c # -# Security functions that we've added to the C library and -# use for secure output. +# libtest161 shared code and security functions # -file ../common/libc/secure/secure.c -file ../common/libc/secure/sha256.c +file ../common/libtest161/test161.c +file ../common/libtest161/secure.c +file ../common/libtest161/sha256.c ######################################## # # diff --git a/kern/include/kern/secret.h b/kern/include/kern/secret.h index 2b725e8..fb32341 100644 --- a/kern/include/kern/secret.h +++ b/kern/include/kern/secret.h @@ -44,7 +44,7 @@ * allows normally compilation and operation. */ -#undef SECRET_TESTING +#define SECRET_TESTING #define SECRET "SECRET" #endif /* _SECRET_H_ */ diff --git a/kern/include/kern/test161.h b/kern/include/kern/test161.h new file mode 100644 index 0000000..2e77009 --- /dev/null +++ b/kern/include/kern/test161.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 + * The President and Fellows of Harvard College. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _KERN_TEST161_H_ +#define _KERN_TEST161_H_ + +#define TEST161_SUCCESS 0 +#define TEST161_FAIL 1 + +#include + +int success(int, const char *, const char *); +int secprintf(const char *secret, const char *msg, const char *name); + +#endif /* _KERN_TEST161_H_ */ diff --git a/kern/include/test.h b/kern/include/test.h index cbd0a34..e978a00 100644 --- a/kern/include/test.h +++ b/kern/include/test.h @@ -178,13 +178,6 @@ int ll1test(int, char **); int ll16test(int, char **); #endif -#define SUCCESS 0 -#define FAIL 1 - -int success(bool, const char *, const char *); - -int ksecprintf(const char *secret, const char *msg, const char *name); - void random_yielder(uint32_t); void random_spinner(uint32_t); diff --git a/kern/test/lib.c b/kern/test/lib.c index c373e08..00e5ebb 100644 --- a/kern/test/lib.c +++ b/kern/test/lib.c @@ -1,65 +1,7 @@ -#include #include #include #include #include -#include - -/* - * Common success function for kernel tests. If SECRET_TESTING is defined, - * ksecprintf will compute the hmac/sha256 hash of any message using the - * shared secret and a random salt value. The (secure) server also knows - * the secret and can verify the message was generated by a trusted source. - * The salt value prevents against replay attacks. - */ -int -success(bool status, const char * secret, const char * name) { - if (status == SUCCESS) { - return ksecprintf(secret, "SUCCESS", name); - } else { - return ksecprintf(secret, "FAIL", name); - } -} - -#ifndef SECRET_TESTING - -int -ksecprintf(const char * secret, const char * msg, const char * name) -{ - (void)secret; - return kprintf("%s: %s\n", name, msg); -} - -#else - -int -ksecprintf(const char * secret, const char * msg, const char * name) -{ - char *hash, *salt, *fullmsg; - int res; - size_t len; - - hash = salt = fullmsg = NULL; - - // test161 expects "name: msg" - len = strlen(name) + strlen(msg) + 3; // +3 for " :" and null terminator - fullmsg = (char *)kmalloc(len); - KASSERT(fullmsg != NULL); - snprintf(fullmsg, len, "%s: %s", name, msg); - - res = hmac_salted(fullmsg, len-1, secret, strlen(secret), &hash, &salt); - KASSERT(res == 0); - - res = kprintf("(%s, %s, %s, %s: %s)\n", name, hash, salt, name, msg); - - kfree(hash); - kfree(salt); - kfree(fullmsg); - - return res; -} - -#endif /* * Helper functions used by testing and problem driver code diff --git a/kern/test/rwtest.c b/kern/test/rwtest.c index 1c272dc..cbb3dcc 100644 --- a/kern/test/rwtest.c +++ b/kern/test/rwtest.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include /* @@ -21,7 +21,7 @@ int rwtest(int nargs, char **args) { (void)args; kprintf_n("rwt1 unimplemented\n"); - success(FAIL, SECRET, "rwt1"); + success(TEST161_FAIL, SECRET, "rwt1"); return 0; } @@ -31,7 +31,7 @@ int rwtest2(int nargs, char **args) { (void)args; kprintf_n("rwt2 unimplemented\n"); - success(FAIL, SECRET, "rwt2"); + success(TEST161_FAIL, SECRET, "rwt2"); return 0; } @@ -41,7 +41,7 @@ int rwtest3(int nargs, char **args) { (void)args; kprintf_n("rwt3 unimplemented\n"); - success(FAIL, SECRET, "rwt3"); + success(TEST161_FAIL, SECRET, "rwt3"); return 0; } @@ -51,7 +51,7 @@ int rwtest4(int nargs, char **args) { (void)args; kprintf_n("rwt4 unimplemented\n"); - success(FAIL, SECRET, "rwt4"); + success(TEST161_FAIL, SECRET, "rwt4"); return 0; } @@ -61,7 +61,7 @@ int rwtest5(int nargs, char **args) { (void)args; kprintf_n("rwt5 unimplemented\n"); - success(FAIL, SECRET, "rwt5"); + success(TEST161_FAIL, SECRET, "rwt5"); return 0; } diff --git a/kern/test/synchprobs.c b/kern/test/synchprobs.c index 275280e..3948ab0 100644 --- a/kern/test/synchprobs.c +++ b/kern/test/synchprobs.c @@ -9,14 +9,14 @@ #include #include #include -#include +#include #include #define PROBLEMS_MAX_YIELDER 16 #define PROBLEMS_MAX_SPINNER 8192 -#define SUCCESS 0 -#define FAIL 1 +#define TEST161_SUCCESS 0 +#define TEST161_FAIL 1 /* * Shared initialization routines @@ -29,7 +29,7 @@ static struct semaphore *startsem; static struct semaphore *endsem; struct spinlock status_lock; -static bool test_status = FAIL; +static bool test_status = TEST161_FAIL; const char *test_message; static @@ -37,7 +37,7 @@ bool failif(bool condition, const char *message) { if (condition) { spinlock_acquire(&status_lock); - test_status = FAIL; + test_status = TEST161_FAIL; test_message = message; spinlock_release(&status_lock); } @@ -273,7 +273,7 @@ whalemating(int nargs, char **args) { panic("sp1: sem_create failed\n"); } spinlock_init(&status_lock); - test_status = SUCCESS; + test_status = TEST161_SUCCESS; test_message = ""; whalemating_init(); @@ -308,18 +308,18 @@ whalemating(int nargs, char **args) { } /* Make sure nothing is happening... */ - loop_status = SUCCESS; - for (i = 0; i < CHECK_TIMES && loop_status == SUCCESS; i++) { + loop_status = TEST161_SUCCESS; + for (i = 0; i < CHECK_TIMES && loop_status == TEST161_SUCCESS; i++) { kprintf_t("."); random_spinner(PROBLEMS_MAX_SPINNER); lock_acquire(testlock); if ((male_start_count != NMATING) || (female_start_count != NMATING) || (matchmaker_start_count + male_end_count + female_end_count + matchmaker_end_count != 0)) { - loop_status = FAIL; + loop_status = TEST161_FAIL; } lock_release(testlock); } - if (failif((loop_status == FAIL), "failed: uncoordinated matchmaking is occurring")) { + if (failif((loop_status == TEST161_FAIL), "failed: uncoordinated matchmaking is occurring")) { goto done; } @@ -352,19 +352,19 @@ whalemating(int nargs, char **args) { } /* Make sure nothing else is happening... */ - loop_status = SUCCESS; - for (i = 0; i < CHECK_TIMES && loop_status == SUCCESS; i++) { + loop_status = TEST161_SUCCESS; + for (i = 0; i < CHECK_TIMES && loop_status == TEST161_SUCCESS; i++) { kprintf_t("."); random_spinner(PROBLEMS_MAX_SPINNER); lock_acquire(testlock); if ((male_start_count != NMATING) || (female_start_count != NMATING) || (matchmaker_start_count != pivot) || (male_end_count != pivot) || (female_end_count != pivot) || (matchmaker_end_count != pivot)) { - loop_status = FAIL; + loop_status = TEST161_FAIL; } lock_release(testlock); } - if (failif((loop_status == FAIL), "failed: uncoordinated matchmaking is occurring")) { + if (failif((loop_status == TEST161_FAIL), "failed: uncoordinated matchmaking is occurring")) { goto done; } @@ -399,8 +399,8 @@ done: sem_destroy(matcher_sem); kprintf_t("\n"); - if (test_status != SUCCESS) { - ksecprintf(SECRET, test_message, "sp1"); + if (test_status != TEST161_SUCCESS) { + secprintf(SECRET, test_message, "sp1"); } success(test_status, SECRET, "sp1"); @@ -628,7 +628,7 @@ int stoplight(int nargs, char **args) { panic("sp2: sem_create failed\n"); } spinlock_init(&status_lock); - test_status = SUCCESS; + test_status = TEST161_SUCCESS; stoplight_init(); @@ -669,7 +669,7 @@ int stoplight(int nargs, char **args) { for (i = 0; i < NCARS; i++) { passed += car_locations[i] == PASSED_CAR ? 1 : 0; } - if ((test_status == SUCCESS) && + if ((test_status == TEST161_SUCCESS) && (!(failif((passed != NCARS), "failed: not enough cars"))) && (!(failif((all_quadrant != required_quadrant), "failed: didn't do the right turns"))) && (!(failif((max_car_count <= 1), "failed: no concurrency achieved")))) {}; @@ -679,8 +679,8 @@ int stoplight(int nargs, char **args) { sem_destroy(endsem); kprintf_t("\n"); - if (test_status != SUCCESS) { - ksecprintf(SECRET, test_message, "sp2"); + if (test_status != TEST161_SUCCESS) { + secprintf(SECRET, test_message, "sp2"); } success(test_status, SECRET, "sp2"); diff --git a/kern/test/synchtest.c b/kern/test/synchtest.c index 8d5b28e..23bb151 100644 --- a/kern/test/synchtest.c +++ b/kern/test/synchtest.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #define CREATELOOPS 8 @@ -63,7 +63,7 @@ static struct cv *testcv = NULL; static struct semaphore *donesem = NULL; struct spinlock status_lock; -static bool test_status = FAIL; +static bool test_status = TEST161_FAIL; static unsigned long semtest_current; @@ -72,7 +72,7 @@ bool failif(bool condition) { if (condition) { spinlock_acquire(&status_lock); - test_status = FAIL; + test_status = TEST161_FAIL; spinlock_release(&status_lock); } return condition; @@ -131,7 +131,7 @@ semtest(int nargs, char **args) } } spinlock_init(&status_lock); - test_status = SUCCESS; + test_status = TEST161_SUCCESS; kprintf_n("If this hangs, it's broken: "); P(testsem); @@ -264,7 +264,7 @@ locktest(int nargs, char **args) } } spinlock_init(&status_lock); - test_status = SUCCESS; + test_status = TEST161_SUCCESS; for (i=0; i #include #include -#include +#include #include /* @@ -838,7 +838,7 @@ kheap_printused(void) char total_string[32]; snprintf(total_string, sizeof(total_string), "%lu", total); - ksecprintf(SECRET, total_string, "khu"); + secprintf(SECRET, total_string, "khu"); } //////////////////////////////////////// diff --git a/mk/os161.config.mk b/mk/os161.config.mk index bc96419..b77fcc6 100644 --- a/mk/os161.config.mk +++ b/mk/os161.config.mk @@ -470,7 +470,7 @@ MORECFLAGS+=-I$(INSTALLTOP)/include LDFLAGS+=-nostdlib -L$(INSTALLTOP)/lib $(INSTALLTOP)/lib/crt0.o MORELIBS+=-lc LIBDEPS+=$(INSTALLTOP)/lib/crt0.o $(INSTALLTOP)/lib/libc.a - +LIBS+=-ltest161 ############################################################ # end. diff --git a/userland/Makefile b/userland/Makefile index 0ad87da..4ec29c1 100644 --- a/userland/Makefile +++ b/userland/Makefile @@ -12,6 +12,7 @@ INCLUDES=\ include include \ include/sys include/sys \ include/test include/test \ + include/test161 include/test161 \ include/types include/types INCLUDELINKS=\ diff --git a/userland/include/secure.h b/userland/include/test161/secure.h similarity index 100% rename from userland/include/secure.h rename to userland/include/test161/secure.h diff --git a/userland/include/test161/test161.h b/userland/include/test161/test161.h new file mode 100644 index 0000000..0dcba23 --- /dev/null +++ b/userland/include/test161/test161.h @@ -0,0 +1,6 @@ +#ifndef _TEST161_H_ +#define _TEST161_H_ + +#include + +#endif // _TEST161_H diff --git a/userland/lib/Makefile b/userland/lib/Makefile index 842056c..54fbe24 100644 --- a/userland/lib/Makefile +++ b/userland/lib/Makefile @@ -8,6 +8,6 @@ TOP=../.. .include "$(TOP)/mk/os161.config.mk" -SUBDIRS=crt0 libc libtest hostcompat +SUBDIRS=crt0 libc libtest libtest161 hostcompat .include "$(TOP)/mk/os161.subdir.mk" diff --git a/userland/lib/libc/Makefile b/userland/lib/libc/Makefile index 45c69d0..9955311 100644 --- a/userland/lib/libc/Makefile +++ b/userland/lib/libc/Makefile @@ -13,11 +13,6 @@ SRCS+=\ $(COMMON)/printf/snprintf.c \ $(COMMON)/printf/tprintf.c -# secure -SRCS+=\ - $(COMMON)/secure/secure.c \ - $(COMMON)/secure/sha256.c \ - # stdio SRCS+=\ stdio/__puts.c \ diff --git a/userland/lib/libtest161/Makefile b/userland/lib/libtest161/Makefile new file mode 100644 index 0000000..ecb9138 --- /dev/null +++ b/userland/lib/libtest161/Makefile @@ -0,0 +1,17 @@ +# +# libtest - library of common test support code +# + +TOP=../../.. +.include "$(TOP)/mk/os161.config.mk" + +COMMON=$(TOP)/common/libtest161 + +SRCS+=\ + $(COMMON)/secure.c \ + $(COMMON)/sha256.c \ + $(COMMON)/test161.c \ + +LIB=test161 + +.include "$(TOP)/mk/os161.lib.mk"