Merge branch 'master' of gitlab.ops-class.org:staff/os161

This commit is contained in:
Yihong Chen
2016-02-01 10:40:46 -05:00
18 changed files with 3554 additions and 96 deletions

99
kern/test/hmacunit.c Normal file
View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2015
* 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.
*/
#include <types.h>
#include <lib.h>
#include <spinlock.h>
#include <synch.h>
#include <thread.h>
#include <current.h>
#include <clock.h>
#include <test.h>
#include <kern/secure.h>
/*
* Unit tests for hmac/sha256 hashing.
*/
////////////////////////////////////////////////////////////
// support code
static
void
ok(void)
{
kprintf("Test passed.\n");
}
/*
* Unit test 1
*
* Test some known msg/key/hashes to make sure we produce the
* right results.
*/
static const char *plaintext1[] = {
"The quick brown fox jumps over the lazy dog",
"The only people for me are the mad ones",
"I don't exactly know what I mean by that, but I mean it.",
};
static const char *keys1[] = {
"xqWmgzbvGuLIeeKOrwMA",
"ZxuvolLXL7C68pDjsclX",
"PYeuVzKuB03awYDgJotS",
};
static const char *hashes1[] = {
"251ab1da03c94435daf44898fcd11606669e222270e4ac90d04a18a9df8fdfd6",
"75bbf48c53ccba08c244447ef7eff2e0a02f23acfdac6502282ec431823fb393",
"6d7d2b5eabcda504f26de7547185483b19f9953a6eaeec6c364bb45e20b28598",
};
#define N_TESTS_1 3
int
hmacu1(int nargs, char **args)
{
char *hash;
int res;
(void)nargs; (void)args;
int i;
for (i = 0; i < N_TESTS_1; i++)
{
res = hmac(plaintext1[i], strlen(plaintext1[i]), keys1[i], strlen(keys1[i]), &hash);
KASSERT(!res);
KASSERT(strcmp(hash, hashes1[i]) == 0);
kfree(hash);
}
ok();
/* clean up */
return 0;
}

View File

@@ -1,6 +1,58 @@
#include <kern/secret.h>
#include <types.h>
#include <thread.h>
#include <test.h>
#include <lib.h>
/*
* Main success function for kernel tests. Prints a multiple of the secret if
* the secret is non-zero and the test succeeded. Otherwise prints a random
* number.
*
* Ideally we would multiply the secret (a large prime) by another large prime
* to ensure that factoring was hard, but that would require either primality
* testing (slow) or augmenting sys161 with a prime number generator. This is
* sufficient for now to prevent replay attacks.
*/
#define MIN_MULTIPLIER 0x80000000
#ifndef SECRET_TESTING
void
success(bool status, uint32_t secret, const char * name) {
(void)secret;
if (status == SUCCESS) {
kprintf("%s: SUCCESS\n", name);
} else {
kprintf("%s: FAIL\n", name);
}
return;
}
#else
void
success(bool status, uint32_t secret, const char * name) {
uint32_t multiplier;
// Make sure we can get large random numbers
KASSERT(randmax() == 0xffffffff);
while (1) {
multiplier = random();
// We can at least remove the obvious non-primes...
if (multiplier % 2 == 0) {
continue;
}
if (multiplier > MIN_MULTIPLIER) {
break;
}
}
uint64_t big_secret = (uint64_t) secret * (uint64_t) multiplier;
if (status == SUCCESS) {
kprintf("%s: SUCCESS (%llu)\n", name, big_secret);
} else {
kprintf("%s: FAIL (%llu)\n", name, big_secret);
}
return;
}
#endif
/*
* Helper functions used by testing and problem driver code

View File

@@ -78,14 +78,14 @@ male_start(uint32_t index) {
(void)index;
random_yielder(PROBLEMS_MAX_YIELDER);
random_spinner(PROBLEMS_MAX_SPINNER);
tkprintf("%s starting\n", curthread->t_name);
kprintf_n("%s starting\n", curthread->t_name);
}
void
male_end(uint32_t index) {
(void)index;
random_yielder(PROBLEMS_MAX_YIELDER);
random_spinner(PROBLEMS_MAX_SPINNER);
tkprintf("%s ending\n", curthread->t_name);
kprintf_n("%s ending\n", curthread->t_name);
}
static
@@ -112,14 +112,14 @@ female_start(uint32_t index) {
(void) index;
random_yielder(PROBLEMS_MAX_YIELDER);
random_spinner(PROBLEMS_MAX_SPINNER);
tkprintf("%s starting\n", curthread->t_name);
kprintf_n("%s starting\n", curthread->t_name);
}
void
female_end(uint32_t index) {
(void) index;
random_yielder(PROBLEMS_MAX_YIELDER);
random_spinner(PROBLEMS_MAX_SPINNER);
tkprintf("%s ending\n", curthread->t_name);
kprintf_n("%s ending\n", curthread->t_name);
}
static
@@ -146,14 +146,14 @@ matchmaker_start(uint32_t index) {
(void)index;
random_yielder(PROBLEMS_MAX_YIELDER);
random_spinner(PROBLEMS_MAX_SPINNER);
tkprintf("%s starting\n", curthread->t_name);
kprintf_n("%s starting\n", curthread->t_name);
}
void
matchmaker_end(uint32_t index) {
(void)index;
random_yielder(PROBLEMS_MAX_YIELDER);
random_spinner(PROBLEMS_MAX_SPINNER);
tkprintf("%s ending\n", curthread->t_name);
kprintf_n("%s ending\n", curthread->t_name);
}
#define NMATING 10
@@ -267,7 +267,7 @@ inQuadrant(int quadrant, uint32_t index) {
random_yielder(PROBLEMS_MAX_YIELDER);
random_spinner(PROBLEMS_MAX_SPINNER);
tkprintf("%s in quadrant %d\n", curthread->t_name, quadrant);
kprintf_n("%s in quadrant %d\n", curthread->t_name, quadrant);
}
void
@@ -276,7 +276,7 @@ leaveIntersection(uint32_t index) {
random_yielder(PROBLEMS_MAX_YIELDER);
random_spinner(PROBLEMS_MAX_SPINNER);
tkprintf("%s left the intersection\n", curthread->t_name);
kprintf_n("%s left the intersection\n", curthread->t_name);
}
#define NCARS 64

View File

@@ -40,9 +40,6 @@
#include <kern/secret.h>
#include <spinlock.h>
#define SUCCESS 0
#define FAIL 1
#define NSEMLOOPS 63
#define NLOCKLOOPS 120
#define NCVLOOPS 5
@@ -94,15 +91,6 @@ inititems(void)
spinlock_init(&status_lock);
}
static
void
success(bool status, const char *msg) {
if (status == SUCCESS) {
kprintf("%s%s: SUCCESS\n", KERNEL_SECRET, msg);
} else {
kprintf("%s%s: FAIL\n", KERNEL_SECRET, msg);
}
}
static
void
@@ -117,10 +105,10 @@ semtestthread(void *junk, unsigned long num)
random_yielder(4);
P(testsem);
semtest_current = num;
tkprintf("Thread %2lu: ", num);
kprintf_n("Thread %2lu: ", num);
for (i=0; i<NSEMLOOPS; i++) {
tkprintf("%c", (int)num+64);
kprintf_n("%c", (int)num+64);
random_yielder(4);
if (semtest_current != num) {
spinlock_acquire(&status_lock);
@@ -129,7 +117,7 @@ semtestthread(void *junk, unsigned long num)
}
}
tkprintf("\n");
kprintf_n("\n");
V(donesem);
}
@@ -143,12 +131,12 @@ semtest(int nargs, char **args)
inititems();
test_status = FAIL;
tkprintf("Starting semaphore test...\n");
tkprintf("If this hangs, it's broken: ");
kprintf_n("Starting semaphore test...\n");
kprintf_n("If this hangs, it's broken: ");
P(testsem);
P(testsem);
test_status = SUCCESS;
tkprintf("ok\n");
kprintf_n("ok\n");
for (i=0; i<NTHREADS; i++) {
result = thread_fork("semtest", NULL, semtestthread, NULL, i);
@@ -167,8 +155,8 @@ semtest(int nargs, char **args)
V(testsem);
V(testsem);
tkprintf("Semaphore test done.\n");
success(test_status, "semtest");
kprintf_n("Semaphore test done.\n");
success(test_status, SECRET, "sy1");
return 0;
}
@@ -177,8 +165,8 @@ static
void
fail(unsigned long num, const char *msg)
{
tkprintf("thread %lu: Mismatch on %s\n", num, msg);
tkprintf("Test failed\n");
kprintf_n("thread %lu: Mismatch on %s\n", num, msg);
kprintf_n("Test failed\n");
lock_release(testlock);
@@ -251,7 +239,7 @@ locktest(int nargs, char **args)
inititems();
test_status = SUCCESS;
tkprintf("Starting lock test...\n");
kprintf_n("Starting lock test...\n");
for (i=0; i<NTHREADS; i++) {
result = thread_fork("synchtest", NULL, locktestthread, NULL, i);
@@ -263,8 +251,8 @@ locktest(int nargs, char **args)
P(donesem);
}
tkprintf("Lock test done.\n");
success(test_status, "locktest");
kprintf_n("Lock test done.\n");
success(test_status, SECRET, "sy2");
return 0;
}
@@ -294,8 +282,8 @@ cvtestthread(void *junk, unsigned long num)
/* Require at least 2000 cpu cycles (we're 25mhz) */
if (ts2.tv_sec == 0 && ts2.tv_nsec < 40*2000) {
tkprintf("cv_wait took only %u ns\n", ts2.tv_nsec);
tkprintf("That's too fast... you must be " "busy-looping\n");
kprintf_n("cv_wait took only %u ns\n", ts2.tv_nsec);
kprintf_n("That's too fast... you must be " "busy-looping\n");
spinlock_acquire(&status_lock);
test_status = FAIL;
spinlock_release(&status_lock);
@@ -323,7 +311,7 @@ cvtestthread(void *junk, unsigned long num)
}
spinlock_release(&status_lock);
tkprintf("Thread %lu\n", testval2);
kprintf_n("Thread %lu\n", testval2);
testval1 = (testval1 + NTHREADS - 1) % NTHREADS;
lock_release(testlock);
}
@@ -339,8 +327,8 @@ cvtest(int nargs, char **args)
(void)args;
inititems();
tkprintf("Starting CV test...\n");
tkprintf("Threads should print out in reverse order.\n");
kprintf_n("Starting CV test...\n");
kprintf_n("Threads should print out in reverse order.\n");
testval1 = NTHREADS-1;
@@ -354,8 +342,8 @@ cvtest(int nargs, char **args)
P(donesem);
}
tkprintf("CV test done\n");
success(test_status, "cvtest");
kprintf_n("CV test done\n");
success(test_status, SECRET, "sy3");
return 0;
}
@@ -401,7 +389,7 @@ sleepthread(void *junk1, unsigned long junk2)
random_yielder(4);
lock_release(testlocks[i]);
}
tkprintf("sleepthread: %u\n", j);
kprintf_n("sleepthread: %u\n", j);
}
V(exitsem);
}
@@ -434,7 +422,7 @@ wakethread(void *junk1, unsigned long junk2)
random_yielder(4);
lock_release(testlocks[i]);
}
tkprintf("wakethread: %u\n", j);
kprintf_n("wakethread: %u\n", j);
}
V(exitsem);
}
@@ -458,7 +446,7 @@ cvtest2(int nargs, char **args)
gatesem = sem_create("gatesem", 0);
exitsem = sem_create("exitsem", 0);
tkprintf("cvtest2...\n");
kprintf_n("cvtest2...\n");
result = thread_fork("cvtest2", NULL, sleepthread, NULL, 0);
if (result) {
@@ -482,8 +470,8 @@ cvtest2(int nargs, char **args)
testcvs[i] = NULL;
}
tkprintf("cvtest2 done\n");
success(test_status, "cvtest2");
kprintf_n("cvtest2 done\n");
success(test_status, SECRET, "sy4");
return 0;
}
@@ -497,8 +485,8 @@ int rwtest(int nargs, char **args) {
(void) nargs;
(void) args;
tkprintf("rwtest unimplemented\n");
success(FAIL, "rwtest");
kprintf_n("rwtest unimplemented\n");
success(FAIL, SECRET, "sy5");
return 0;
}