diff --git a/demos/auth.c b/demos/auth.c index bcabbb69..f7179e1d 100644 --- a/demos/auth.c +++ b/demos/auth.c @@ -44,14 +44,9 @@ auth(void) puts("Example: crypto_auth\n"); - memset(key, 0, sizeof key); - prompt_input("Enter a key > ", (char*)key, sizeof key); - puts("Complete key:"); - print_hex(key, sizeof key); - putchar('\n'); + prompt_input("a key", (char*)key, sizeof key, 0); - message_len = prompt_input("Enter a message > ", - (char*)message, sizeof message); + message_len = prompt_input("a message", (char*)message, sizeof message, 1); putchar('\n'); printf("Generating %s authentication...\n", crypto_auth_primitive()); diff --git a/demos/box.c b/demos/box.c index 09693f42..d81f4543 100644 --- a/demos/box.c +++ b/demos/box.c @@ -96,8 +96,7 @@ box(void) putchar('\n'); /* read input */ - message_len = prompt_input("Enter a message > ", - (char*)message, sizeof message); + message_len = prompt_input("a message", (char*)message, sizeof message, 1); print_hex(message, message_len); putchar('\n'); diff --git a/demos/box_detached.c b/demos/box_detached.c index c37307cb..ec3c834a 100644 --- a/demos/box_detached.c +++ b/demos/box_detached.c @@ -96,8 +96,7 @@ box_detached(void) putchar('\n'); /* read input */ - message_len = prompt_input("Enter a message > ", - (char*)message, sizeof message); + message_len = prompt_input("a message", (char*)message, sizeof message, 1); print_hex(message, message_len); putchar('\n'); diff --git a/demos/generichash.c b/demos/generichash.c index ecb26d17..1e4d15fc 100644 --- a/demos/generichash.c +++ b/demos/generichash.c @@ -11,34 +11,68 @@ #include "utils.h" /* utility functions shared by demos */ /* - * Generic hash is intended as a variable output hash with enough strength - * to ensure data integrity. The hash out put is also able to vary in size. - * Key is optional and is able to vary in size. + * This function computes a fixed-length fingerprint for an arbitrary long message. * - * Note that it is recommended to stay within the range of MIN and MAX - * output because larger output will produce gaps. + * Sample use cases: + * + * File integrity checking + * Creating unique identifiers to index arbitrary long data + * + * The crypto_generichash() function puts a fingerprint of the + * message in whose length is inlen bytes into out. The output size + * can be chosen by the application. + * + * The minimum recommended output size is crypto_generichash_BYTES. + * This size makes it practically impossible for two messages to + * produce the same fingerprint. + * + * But for specific use cases, the size can be any value between + * crypto_generichash_BYTES_MIN (included) and + * crypto_generichash_BYTES_MAX (included). + * + * key can be NULL and keylen can be 0. In this case, a message will + * always have the same fingerprint, similar to the MD5 or SHA-1 + * functions for which crypto_generichash() is a faster and more + * secure alternative. + * + * But a key can also be specified. A message will always have the + * same fingerprint for a given key, but different keys used to hash + * the same message are very likely to produce distinct fingerprints. + * + * In particular, the key can be used to make sure that different + * applications generate different fingerprints even if they process + * the same data. + * + * The recommended key size is crypto_generichash_KEYBYTES bytes. + * + * However, the key size can by any value between + * crypto_generichash_KEYBYTES_MIN (included) and + * crypto_generichash_KEYBYTES_MAX (included). */ void generichash(void) { - unsigned char k[crypto_generichash_KEYBYTES_MAX]; /* key */ - unsigned char h[crypto_generichash_BYTES_MIN]; /* hash output */ - unsigned char m[MAX_INPUT_SIZE]; /* message */ - size_t mlen; /* length */ + unsigned char key[crypto_generichash_KEYBYTES_MAX]; + unsigned char hash[crypto_generichash_BYTES_MIN]; + unsigned char message[MAX_INPUT_SIZE]; + size_t message_len; + size_t key_len; puts("Example: crypto_generichash\n"); - memset(k, 0, sizeof k); - prompt_input("Input your key > ", (char*)k, sizeof k); + key_len = prompt_input("a key", (char*)key, sizeof key, 1); - mlen = prompt_input("Input your message > ", (char*)m, sizeof m); + message_len = prompt_input("a message", (char*)message, sizeof message, 1); putchar('\n'); printf("Hashing message with %s\n", crypto_generichash_primitive()); - crypto_generichash(h, sizeof h, m, mlen, k, sizeof k); - fputs("Hash: ", stdout); - print_hex(h, sizeof h); - putchar('\n'); + if (crypto_generichash(hash, sizeof hash, message, message_len, + key, key_len) != 0) { + puts("Couldn't hash the message, probably due to the key length"); + } else { + fputs("Hash: ", stdout); + print_hex(hash, sizeof hash); + } putchar('\n'); } diff --git a/demos/generichashstream.c b/demos/generichashstream.c index 6f8e2119..25cb2b88 100644 --- a/demos/generichashstream.c +++ b/demos/generichashstream.c @@ -26,8 +26,7 @@ generichashstream(void) puts("Example: crypto_generichashstream\n"); - memset(k, 0, sizeof k); - prompt_input("Input your key > ", (char*)k, sizeof k); + prompt_input("a key", (char*)k, sizeof k, 0); putchar('\n'); printf("Hashing message with %s\n", crypto_generichash_primitive()); @@ -35,8 +34,8 @@ generichashstream(void) /* initialize the stream */ crypto_generichash_init(&state, k, sizeof k, sizeof h); - while (1) { - mlen = prompt_input("> ", (char*)m, sizeof m); + for(;;) { + mlen = prompt_input("the next part of the message", (char*)m, sizeof m); if (mlen == 0) break; diff --git a/demos/shorthash.c b/demos/shorthash.c index 11d54c16..b526397d 100644 --- a/demos/shorthash.c +++ b/demos/shorthash.c @@ -42,11 +42,9 @@ shorthash(void) puts("Example: crypto_shorthash\n"); - memset(key, 0, sizeof key); - prompt_input("Enter a key > ", (char*)key, sizeof key); + prompt_input("a key", (char*)key, sizeof key, 0); - message_len = prompt_input("Enter a message > ", - (char*)message, sizeof message); + message_len = prompt_input("a message", (char*)message, sizeof message, 1); putchar('\n'); printf("Hashing the message with %s\n", crypto_shorthash_primitive()); diff --git a/demos/sign.c b/demos/sign.c index 6107c642..49b6568e 100644 --- a/demos/sign.c +++ b/demos/sign.c @@ -43,8 +43,8 @@ sign(void) puts("\n"); /* read input */ - mlen = prompt_input("Input your message > ", (char*)m, - sizeof m - crypto_sign_BYTES); + mlen = prompt_input("a message", (char*)m, + sizeof m - crypto_sign_BYTES, 1); putc('\n', stdout); puts("Notice the message has no prepended padding"); diff --git a/demos/utils.c b/demos/utils.c index ee7f6fee..428955f0 100644 --- a/demos/utils.c +++ b/demos/utils.c @@ -45,22 +45,44 @@ print_hex(const void *bin, const size_t bin_len) * trailing newline characters. */ size_t -prompt_input(char *prompt, char *input, const size_t max_input_len) +prompt_input(const char *prompt, char *input, const size_t max_input_len, + int variable_length) { + char input_tmp[MAX_INPUT_SIZE + 1U]; size_t actual_input_len; - fputs(prompt, stdout); + if (variable_length != 0) { + printf("Enter %s (%zu bytes max) > ", prompt, max_input_len); + } else { + printf("Enter %s (%zu bytes) > ", prompt, max_input_len); + } fflush(stdout); - fgets(input, max_input_len, stdin); /* grab input with room for \0 */ + fgets(input_tmp, sizeof input_tmp, stdin); + actual_input_len = strlen(input_tmp); - actual_input_len = strlen(input); - - /* trim excess new line */ - if (actual_input_len > 0 && input[actual_input_len - 1] == '\n') { - input[actual_input_len - 1] = '\0'; + /* trim \n */ + if (actual_input_len > 0 && input_tmp[actual_input_len - 1] == '\n') { + input_tmp[actual_input_len - 1] = '\0'; --actual_input_len; } - return actual_input_len; + + if (actual_input_len > max_input_len) { + printf("Warning: truncating input to %zu bytes\n", max_input_len); + actual_input_len = max_input_len; + } else if (actual_input_len < max_input_len && variable_length == 0) { + printf("Warning: %zu bytes expected, %zu bytes given: padding with zeros\n", + max_input_len, actual_input_len); + memset(input, 0, max_input_len); + } else { + printf("Length: %zu bytes\n", actual_input_len); + } + + memcpy(input, input_tmp, actual_input_len); + if (variable_length == 0) { + return max_input_len; + } else { + return actual_input_len; + } } /* diff --git a/demos/utils.h b/demos/utils.h index d6890d16..b88347fd 100644 --- a/demos/utils.h +++ b/demos/utils.h @@ -10,7 +10,8 @@ void print_hex(const void *bin, const size_t bin_len); -size_t prompt_input(char *prompt, char *input, const size_t max_input_len); +size_t prompt_input(const char *prompt, char *input, const size_t max_input_len, + int variable_length); void print_verification(int r);