/* * Copyright (C) 2019 Freie Universität Berlin. * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @{ * * @file * @brief Test PBKDF2-sha256 implementation. * * @author Juan Carrano * * This application reads (password, salt, iterations) tuples from the * standard input and outputs the derived key. * * The salt must be base64 encoded. The key is printed as base64. * @} */ #include #include #include #include #include "base64.h" #include "hashes/pbkdf2.h" const char error_message[] = "{error}"; const char input_message[] = "{ready}"; #define LINEBUF_SZ (128) enum TEST_STATE { TEST_READ_PASS, TEST_READ_SALT, TEST_READ_ITERS, TEST_COMPUTE, TEST_ERROR }; static void _clear_input(void) { /* clear input buffer */ int c; while ( (c = getchar()) != '\n' && c != EOF ) { } } int main(void) { static char linebuf[LINEBUF_SZ]; /* There will be a few bytes wasted here */ static char password[LINEBUF_SZ]; static uint8_t salt[LINEBUF_SZ]; static uint8_t key[PBKDF2_KEY_SIZE]; size_t passwd_len = 0, salt_len = 0; int iterations = 0; enum TEST_STATE state = TEST_READ_PASS; _clear_input(); while ((puts(input_message), fgets(linebuf, LINEBUF_SZ, stdin) != NULL)) { char *s_end; int conversion_status, line_len = strlen(linebuf)-1; size_t b64_buff_size; linebuf[line_len] = '\0'; switch (state) { case TEST_READ_PASS: strcpy(password, linebuf); passwd_len = line_len; state++; break; case TEST_READ_SALT: /* work around bug in base64_decode */ if (line_len == 0) { salt_len = 0; conversion_status = BASE64_SUCCESS; } else { salt_len = sizeof(salt); conversion_status = base64_decode((uint8_t*)linebuf, line_len+1, salt, &salt_len); } if (conversion_status == BASE64_SUCCESS) { state++; } else { state = TEST_ERROR; } break; case TEST_READ_ITERS: iterations = strtol(linebuf, &s_end, 10); if (*s_end != '\0') { state = TEST_ERROR; } else { state++; } break; default: assert(1); break; } switch (state) { case TEST_COMPUTE: pbkdf2_sha256((uint8_t*)password, passwd_len, salt, salt_len, iterations, key); b64_buff_size = sizeof(linebuf); conversion_status = base64_encode(key, sizeof(key), (uint8_t*)linebuf, &b64_buff_size); if (conversion_status == BASE64_SUCCESS) { linebuf[b64_buff_size] = 0; puts(linebuf); } else { puts(error_message); } state = TEST_READ_PASS; break; case TEST_ERROR: puts(error_message); state = TEST_READ_PASS; break; default: break; } } return 0; }