diff --git a/kern/include/kern/secret.h b/kern/include/kern/secret.h index a561058..02d0335 100644 --- a/kern/include/kern/secret.h +++ b/kern/include/kern/secret.h @@ -45,6 +45,6 @@ */ #undef SECRET_TESTING -#define SECRET 0 +#define SECRET "" #endif /* _SECRET_H_ */ diff --git a/kern/include/test.h b/kern/include/test.h index 1e7f9ef..aebefbd 100644 --- a/kern/include/test.h +++ b/kern/include/test.h @@ -174,7 +174,9 @@ int ll16test(int, char **); #define SUCCESS 0 #define FAIL 1 -void success(bool, uint32_t, const char *); +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 5f6a5a5..2fe3711 100644 --- a/kern/test/lib.c +++ b/kern/test/lib.c @@ -3,55 +3,54 @@ #include #include #include +#include /* - * 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. + * 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. */ - -#define MIN_MULTIPLIER 0x80000000 +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 -void -success(bool status, uint32_t secret, const char * name) { + +int +ksecprintf(const char * secret, const char * msg, const char * name) +{ (void)secret; - if (status == SUCCESS) { - kprintf("%s: SUCCESS\n", name); - } else { - kprintf("%s: FAIL\n", name); - } - return; + return kprintf("%s: %s\n", name, msg); } + #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; + +int +ksecprintf(const char * secret, const char * msg, const char * name) +{ + char *hash; + char *salt; + int res; + + res = hmac_salted(msg, strlen(msg), secret, strlen(secret), &hash, &salt); + if (res) + return -res; + + res = kprintf("(%s, %s, %s, %s: %s)\n", name, hash, salt, name, msg); + + kfree(hash); + kfree(salt); + + return res; } + #endif /*