Nettle C Program for generating pbkdf2-sha512 hash
All checks were successful
Run tests / run_tests (push) Successful in 1m15s
All checks were successful
Run tests / run_tests (push) Successful in 1m15s
This commit is contained in:
parent
3ec207ea9b
commit
b7fdfe57e6
3
.clang-format
Normal file
3
.clang-format
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 4
|
|
@ -10,3 +10,7 @@ charset = utf-8
|
||||||
[*.nix]
|
[*.nix]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.c]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
|
@ -46,5 +46,12 @@
|
||||||
# Run all tests for all systems
|
# Run all tests for all systems
|
||||||
hydraJobs = forAllSystems tests;
|
hydraJobs = forAllSystems tests;
|
||||||
checks = forAllSystems tests;
|
checks = forAllSystems tests;
|
||||||
|
devShell.x86_64-linux = let
|
||||||
|
pkgs = import nixpkgs {system = "x86_64-linux";};
|
||||||
|
in
|
||||||
|
pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs; [bear gcc nettle];
|
||||||
|
nativeBuildInputs = [pkgs.nettle];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
150
modules/pbkdf2-sha512.c
Normal file
150
modules/pbkdf2-sha512.c
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/random.h>
|
||||||
|
|
||||||
|
#include <nettle/pbkdf2.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define DEBUG(...) \
|
||||||
|
if (debug) \
|
||||||
|
printf(__VA_ARGS__)
|
||||||
|
|
||||||
|
int uppercase = 0;
|
||||||
|
int debug = 0;
|
||||||
|
size_t salt_len;
|
||||||
|
|
||||||
|
static void display_hex(unsigned length, uint8_t *data) {
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < length / 2; i++) {
|
||||||
|
if (uppercase)
|
||||||
|
printf("%02X", data[i]);
|
||||||
|
else
|
||||||
|
printf("%02x", data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void str_to_upper(char *str, size_t len) {
|
||||||
|
for (size_t i = 0u; i < len; i++) {
|
||||||
|
str[i] = toupper(str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *hex_decode(char *hex) {
|
||||||
|
DEBUG("salt: %s\n", hex);
|
||||||
|
size_t size = strlen(hex);
|
||||||
|
// 1 byte = 2 hex characters so that means the length in bytes is size / 2
|
||||||
|
salt_len = size / 2;
|
||||||
|
char *val = malloc(size);
|
||||||
|
char *pos = hex;
|
||||||
|
|
||||||
|
for (size_t count = 0; count < size; count++) {
|
||||||
|
sscanf(pos, "%2hhx", &val[count]);
|
||||||
|
pos += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint8_t *)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
uint8_t *key = NULL;
|
||||||
|
unsigned int iterations = 0;
|
||||||
|
size_t length = 0;
|
||||||
|
uint8_t *salt = NULL;
|
||||||
|
int print_metadata = 1;
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "k:i:l:vnus::")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'k':
|
||||||
|
key = (uint8_t *)optarg;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
iterations = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
length = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
debug = 1;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
print_metadata = 0;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
uppercase = 1;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
salt = hex_decode(optarg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage: %s -k val -i val -l val [-sval]\n"
|
||||||
|
"-k: Key to hash\n"
|
||||||
|
"-i: Iterations/rotations of pbkdf2-sha512 algorithm\n"
|
||||||
|
"-l: Length of output hash\n"
|
||||||
|
"-n: No metadata with hash. Only print hash\n"
|
||||||
|
"-v: Verbose\n"
|
||||||
|
"-u: Output hash in uppercase\n"
|
||||||
|
"-s: The salt to use. If not provided uses random salt (16 "
|
||||||
|
"length)\n",
|
||||||
|
argv[0]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == NULL) {
|
||||||
|
fprintf(stderr, "No key provided");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (iterations == 0) {
|
||||||
|
fprintf(stderr, "Invalid or no iterations provived");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (length == 0) {
|
||||||
|
fprintf(stderr, "Invalid or no length provived");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate salt if none were provided
|
||||||
|
if (salt == NULL) {
|
||||||
|
DEBUG("Generating random salt...");
|
||||||
|
salt_len = 16;
|
||||||
|
salt = malloc(salt_len);
|
||||||
|
getrandom(salt, salt_len, GRND_RANDOM);
|
||||||
|
} else {
|
||||||
|
DEBUG("Using provided salt...");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *buffer = malloc(length + 1);
|
||||||
|
|
||||||
|
DEBUG("Key to hash: %s\n", key);
|
||||||
|
DEBUG("Iterations: %d\n", iterations);
|
||||||
|
DEBUG("Length: %zu\n", length);
|
||||||
|
DEBUG("Salt: %.*s\n", (int)salt_len, (char *)salt);
|
||||||
|
|
||||||
|
pbkdf2_hmac_sha512(strlen((char *)key), key, iterations, salt_len, salt,
|
||||||
|
length, buffer);
|
||||||
|
|
||||||
|
if (print_metadata) {
|
||||||
|
printf("$PBKDF2-SHA512$iterations=%d$", iterations);
|
||||||
|
// salt hex
|
||||||
|
for (int i = 0; i < salt_len; i++) {
|
||||||
|
printf("%02X", salt[i]);
|
||||||
|
}
|
||||||
|
printf("$");
|
||||||
|
}
|
||||||
|
|
||||||
|
display_hex(length, buffer);
|
||||||
|
|
||||||
|
free(salt);
|
||||||
|
free(buffer);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
20
modules/pbkdf2-sha512.nix
Normal file
20
modules/pbkdf2-sha512.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{pkgs ? import <nixpkgs> {}, ...}:
|
||||||
|
pkgs.stdenv.mkDerivation rec {
|
||||||
|
name = "genhash";
|
||||||
|
version = "69.0.0";
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
gcc
|
||||||
|
nettle
|
||||||
|
];
|
||||||
|
|
||||||
|
phases = ["buildPhase"];
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
gcc $src -o $out/${name} -lnettle
|
||||||
|
echo $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
src = ./pbkdf2-sha512.c;
|
||||||
|
}
|
Loading…
Reference in a new issue