mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
62667848c4
This add an implementation of PBKDF2 using sha256 hmac. Only one derived key length is supported (32) though it should not be hard to extend it. The testing is done with both random (with fixed seed) vectors amd vectors from rfc7914.
147 lines
3.7 KiB
C
147 lines
3.7 KiB
C
/*
|
|
* 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 <j.carrano@fu-berlin.de>
|
|
*
|
|
* 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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#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;
|
|
}
|