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]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.c]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
|
|
@ -46,5 +46,12 @@
|
|||
# Run all tests for all systems
|
||||
hydraJobs = 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