cgdconfig(8): Add an argon2id password-based key generation method
This provides an extra level of side-channel and cracking resistance compared to the pre-existing pkcs5_pbkdf2/sha1 method used for password-based disk encryption. Several new keygen parameters are supported: memory (integer, in kilobytes) parallelism (integer, usually the number of CPU cores) version (integer, usually 19...) We do our best to calibrate these automatically when the paramsfile is initially generated. lgtm riastradh@
This commit is contained in:
parent
5a3dc90041
commit
1569bcc0b3
|
@ -0,0 +1,23 @@
|
|||
# $NetBSD: Makefile,v 1.4 2021/11/22 14:34:35 nia Exp $
|
||||
|
||||
LIBISPRIVATE= pic
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
ARGON2DIR= ${NETBSDSRCDIR}/external/apache2/argon2
|
||||
|
||||
.PATH: ${ARGON2DIR}/dist/phc-winner-argon2/src \
|
||||
${ARGON2DIR}/dist/phc-winner-argon2/src/blake2 \
|
||||
${ARGON2DIR}/dist/phc-winner-argon2/include
|
||||
|
||||
LIB= argon2
|
||||
SRCS= argon2.c core.c blake2b.c thread.c encoding.c ref.c
|
||||
|
||||
CFLAGS+= -pthread
|
||||
CPPFLAGS+= -I${ARGON2DIR}/dist/phc-winner-argon2/include
|
||||
|
||||
.if ${MACHINE} == "vax"
|
||||
COPTS.blake2b.c+= -O0
|
||||
.endif
|
||||
|
||||
.include <bsd.lib.mk>
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.292 2021/04/25 23:43:48 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.293 2021/11/22 14:34:35 nia Exp $
|
||||
# from: @(#)Makefile 5.25.1.1 (Berkeley) 5/7/91
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
@ -54,6 +54,10 @@ SUBDIR+= libskey
|
|||
SUBDIR+= libnvmm
|
||||
.endif
|
||||
|
||||
.if (${MKARGON2} != "no")
|
||||
SUBDIR+= ../external/apache2/argon2/lib/libargon2
|
||||
.endif
|
||||
|
||||
.if (${MKMDNS} != "no")
|
||||
SUBDIR+= ../external/apache2/mDNSResponder/lib
|
||||
.endif
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
# $NetBSD: Makefile,v 1.15 2016/07/01 22:50:09 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.16 2021/11/22 14:34:35 nia Exp $
|
||||
|
||||
RUMPPRG=cgdconfig
|
||||
MAN= cgdconfig.8
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SRCS+= cgdconfig.c \
|
||||
cgdlex.l \
|
||||
cgdparse.y \
|
||||
|
@ -10,6 +12,10 @@ SRCS+= cgdconfig.c \
|
|||
params.c \
|
||||
utils.c
|
||||
|
||||
.if ${MKARGON2} != "no"
|
||||
SRCS+= argon2_utils.c
|
||||
.endif
|
||||
|
||||
CPPFLAGS+= -I${.CURDIR} -I. -DYY_NO_INPUT
|
||||
|
||||
YHEADER=1
|
||||
|
@ -17,4 +23,16 @@ YHEADER=1
|
|||
DPADD= ${LIBUTIL} ${LIBCRYPT} ${LIBY} ${LIBL}
|
||||
LDADD= -lutil -lcrypt -ly -ll
|
||||
|
||||
.if ${MKARGON2} != "no"
|
||||
ARGON2DIR= ${NETBSDSRCDIR}/external/apache2/argon2
|
||||
ARGON2OBJDIR!= cd ${ARGON2DIR}/lib/libargon2 && ${PRINTOBJDIR}
|
||||
CPPFLAGS+= -I${NETBSDSRCDIR}/external/apache2/argon2/dist/phc-winner-argon2/include
|
||||
CPPFLAGS+= -DHAVE_ARGON2
|
||||
|
||||
PROGDPLIBS+= argon2 ${ARGON2DIR}/lib/libargon2
|
||||
|
||||
LDADD+= -pthread
|
||||
DPADD+= ${LIBPTHREAD}
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/* $NetBSD: argon2_utils.c,v 1.1 2021/11/22 14:34:35 nia Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2021 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Nia Alarie.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <argon2.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <util.h>
|
||||
#include <err.h>
|
||||
|
||||
#include "argon2_utils.h"
|
||||
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: argon2_utils.c,v 1.1 2021/11/22 14:34:35 nia Exp $");
|
||||
#endif
|
||||
|
||||
static size_t
|
||||
get_cpucount(void)
|
||||
{
|
||||
const int mib[] = { CTL_HW, HW_NCPUONLINE };
|
||||
int ncpuonline = 1;
|
||||
size_t ncpuonline_len = sizeof(ncpuonline);
|
||||
|
||||
if (sysctl(mib, __arraycount(mib),
|
||||
&ncpuonline, &ncpuonline_len, NULL, 0) == -1) {
|
||||
return 1;
|
||||
}
|
||||
return ncpuonline;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
get_usermem(void)
|
||||
{
|
||||
const int mib[] = { CTL_HW, HW_USERMEM64 };
|
||||
uint64_t usermem64 = 0;
|
||||
size_t usermem64_len = sizeof(usermem64);
|
||||
struct rlimit rlim;
|
||||
|
||||
if (sysctl(mib, __arraycount(mib),
|
||||
&usermem64, &usermem64_len, NULL, 0) == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (getrlimit(RLIMIT_AS, &rlim) == -1)
|
||||
return usermem64;
|
||||
if (usermem64 > rlim.rlim_cur && rlim.rlim_cur != RLIM_INFINITY)
|
||||
usermem64 = rlim.rlim_cur;
|
||||
return usermem64; /* bytes */
|
||||
}
|
||||
|
||||
void
|
||||
argon2id_calibrate(size_t keylen, size_t saltlen,
|
||||
size_t *iterations, size_t *memory, size_t *parallelism)
|
||||
{
|
||||
size_t mem = ARGON2_MIN_MEMORY; /* kilobytes */
|
||||
size_t time;
|
||||
const size_t ncpus = get_cpucount();
|
||||
const uint64_t usermem = get_usermem(); /* bytes */
|
||||
struct timespec tp1, tp2;
|
||||
struct timespec delta;
|
||||
unsigned int limit = 0;
|
||||
uint8_t *key = NULL, *salt = NULL;
|
||||
uint8_t tmp_pwd[17]; /* just random data for testing */
|
||||
int ret = ARGON2_OK;
|
||||
|
||||
key = emalloc(keylen);
|
||||
salt = emalloc(saltlen);
|
||||
|
||||
arc4random_buf(tmp_pwd, sizeof(tmp_pwd));
|
||||
arc4random_buf(salt, saltlen);
|
||||
|
||||
/* 1kb to argon2 per 100kb of user memory */
|
||||
mem = usermem / 100000;
|
||||
|
||||
/* 256k: reasonable lower bound from the argon2 test suite */
|
||||
if (mem < 256)
|
||||
mem = 256;
|
||||
|
||||
fprintf(stderr, "calibrating argon2id parameters...");
|
||||
|
||||
/* Decrease 'mem' if it slows down computation too much */
|
||||
|
||||
do {
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tp1) == -1)
|
||||
goto error;
|
||||
if ((ret = argon2_hash(ARGON2_MIN_TIME, mem, ncpus,
|
||||
tmp_pwd, sizeof(tmp_pwd),
|
||||
salt, saltlen,
|
||||
key, keylen,
|
||||
NULL, 0,
|
||||
Argon2_id, ARGON2_VERSION_NUMBER)) != ARGON2_OK) {
|
||||
goto error_argon2;
|
||||
}
|
||||
fprintf(stderr, ".");
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tp2) == -1)
|
||||
goto error;
|
||||
if (timespeccmp(&tp1, &tp2, >))
|
||||
goto error_clock;
|
||||
timespecsub(&tp2, &tp1, &delta);
|
||||
if (delta.tv_sec >= 1)
|
||||
mem /= 2;
|
||||
if (mem < ARGON2_MIN_MEMORY) {
|
||||
mem = ARGON2_MIN_MEMORY;
|
||||
break;
|
||||
}
|
||||
} while (delta.tv_sec >= 1 && (limit++) < 3);
|
||||
|
||||
delta.tv_sec = 0;
|
||||
delta.tv_nsec = 0;
|
||||
|
||||
/* Increase 'time' until we reach a second */
|
||||
|
||||
for (time = ARGON2_MIN_TIME; delta.tv_sec < 1 &&
|
||||
time < ARGON2_MAX_TIME; time <<= 1) {
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tp1) == -1)
|
||||
goto error;
|
||||
if ((ret = argon2_hash(time, mem, ncpus,
|
||||
tmp_pwd, sizeof(tmp_pwd),
|
||||
salt, saltlen,
|
||||
key, keylen,
|
||||
NULL, 0,
|
||||
Argon2_id, ARGON2_VERSION_NUMBER)) != ARGON2_OK) {
|
||||
goto error_argon2;
|
||||
}
|
||||
fprintf(stderr, ".");
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tp2) == -1)
|
||||
goto error;
|
||||
if (timespeccmp(&tp1, &tp2, >))
|
||||
goto error_clock;
|
||||
timespecsub(&tp2, &tp1, &delta);
|
||||
}
|
||||
|
||||
if (time > ARGON2_MIN_TIME)
|
||||
time >>= 1;
|
||||
|
||||
fprintf(stderr, " done\n");
|
||||
|
||||
free(key);
|
||||
free(salt);
|
||||
*iterations = time;
|
||||
*memory = mem;
|
||||
*parallelism = ncpus;
|
||||
return;
|
||||
|
||||
error_argon2:
|
||||
errx(EXIT_FAILURE,
|
||||
" failed to calculate Argon2 hash, error code %d", ret);
|
||||
error_clock:
|
||||
errx(EXIT_FAILURE,
|
||||
" failed to calibrate hash parameters: broken monotonic clock?");
|
||||
error:
|
||||
err(EXIT_FAILURE, " failed to calibrate hash parameters");
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/* $NetBSD: argon2_utils.h,v 1.1 2021/11/22 14:34:35 nia Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2021 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Nia Alarie.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_UTILS_H
|
||||
#define ARGON2_UTILS_H
|
||||
#include <stddef.h>
|
||||
|
||||
void argon2id_calibrate(size_t, size_t, size_t *, size_t *, size_t *);
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: cgdconfig.8,v 1.50 2021/04/30 21:07:34 nia Exp $
|
||||
.\" $NetBSD: cgdconfig.8,v 1.51 2021/11/22 14:34:35 nia Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002, The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
|
@ -27,7 +27,7 @@
|
|||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd April 18, 2021
|
||||
.Dd November 4, 2021
|
||||
.Dt CGDCONFIG 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -164,6 +164,14 @@ evaluates all of the key generation methods in the parameters file
|
|||
and uses the exclusive-or of the outputs of all the methods.
|
||||
The methods and descriptions are as follows:
|
||||
.Bl -tag -width indentxxxxxxxxxxx
|
||||
.It argon2id
|
||||
This method requires a passphrase which is entered at configuration
|
||||
time.
|
||||
Argon2 is a memory-hard password hashing scheme and winner of the
|
||||
2013-2015 Password Hashing Competition.
|
||||
It has numerous parameters allowing its hardness to scale with the
|
||||
performance of the system.
|
||||
Recommended for passphrase-based initialization.
|
||||
.It pkcs5_pbkdf2/sha1
|
||||
This method requires a passphrase which is entered at configuration
|
||||
time.
|
||||
|
@ -231,8 +239,8 @@ scan for a valid FFS file system.
|
|||
.It re-enter
|
||||
prompt for passphrase twice, and ensure entered passphrases are
|
||||
identical.
|
||||
This method only works with the pkcs5_pbkdf2/sha1 and pkcs5_pbkdf2 key
|
||||
generators.
|
||||
This method only works with the argon2id, pkcs5_pbkdf2/sha1, and
|
||||
pkcs5_pbkdf2 key generators.
|
||||
.El
|
||||
.Ss /etc/cgd/cgd.conf
|
||||
The file
|
||||
|
@ -358,10 +366,22 @@ The command to execute.
|
|||
Only used for the shell_cmd key generation method.
|
||||
.It iterations Ar integer
|
||||
The number of iterations.
|
||||
Only used for pkcs5_pbkdf2/sha1 and pkcs5_pbkdf2.
|
||||
Only used for argon2id, pkcs5_pbkdf2/sha1, and pkcs5_pbkdf2.
|
||||
.It salt Ar base64
|
||||
The salt.
|
||||
Only used for pkcs5_pbkdf2/sha1 and pkcs5_pbkdf2.
|
||||
Only used for argon2id, pkcs5_pbkdf2/sha1, and pkcs5_pbkdf2.
|
||||
.It memory Ar integer
|
||||
Memory consumption in kilobytes.
|
||||
Only used for argon2id.
|
||||
.It parallelism Ar integer
|
||||
Number of threads to use to compute the password hash.
|
||||
Should be equivalent to the number of CPUs/hardware threads.
|
||||
Only used for argon2id.
|
||||
.It version Ar integer
|
||||
Version of Argon2 to use.
|
||||
Should be the most recent version, currently
|
||||
.Dv 19 .
|
||||
Only used for argon2id.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width indentxxxxxxxxxxxxxxxxxx -compact
|
||||
|
@ -475,6 +495,15 @@ program's execution.
|
|||
.Xr fstab 5 ,
|
||||
.Xr disklabel 8 ,
|
||||
.Xr gpt 8
|
||||
.Rs
|
||||
.%T "Argon2: the memory-hard function for password hashing and other applications"
|
||||
.%A Alex Biryukov
|
||||
.%A Daniel Dinu
|
||||
.%A Dmitry Khovratovich
|
||||
.%D 2017
|
||||
.%I University of Luxembourg
|
||||
.%U https://www.password-hashing.net/
|
||||
.Re
|
||||
.Pp
|
||||
.Dq PKCS #5 v2.0: Password-Based Cryptography Standard ,
|
||||
RSA Laboratories, March 25, 1999.
|
||||
|
@ -483,5 +512,9 @@ The
|
|||
.Nm
|
||||
utility appeared in
|
||||
.Nx 2.0 .
|
||||
.Pp
|
||||
.Li argon2id
|
||||
support appeared in
|
||||
.Nx 10.0 .
|
||||
.Sh BUGS
|
||||
Pass phrases are limited to 1023 bytes.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cgdconfig.c,v 1.52 2021/06/16 23:22:08 riastradh Exp $ */
|
||||
/* $NetBSD: cgdconfig.c,v 1.53 2021/11/22 14:34:35 nia Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -33,9 +33,12 @@
|
|||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 2002, 2003\
|
||||
The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: cgdconfig.c,v 1.52 2021/06/16 23:22:08 riastradh Exp $");
|
||||
__RCSID("$NetBSD: cgdconfig.c,v 1.53 2021/11/22 14:34:35 nia Exp $");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARGON2
|
||||
#include <argon2.h>
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -113,6 +116,9 @@ static void eliminate_cores(void);
|
|||
static bits_t *getkey(const char *, struct keygen *, size_t);
|
||||
static bits_t *getkey_storedkey(const char *, struct keygen *, size_t);
|
||||
static bits_t *getkey_randomkey(const char *, struct keygen *, size_t, int);
|
||||
#ifdef HAVE_ARGON2
|
||||
static bits_t *getkey_argon2id(const char *, struct keygen *, size_t);
|
||||
#endif
|
||||
static bits_t *getkey_pkcs5_pbkdf2(const char *, struct keygen *, size_t,
|
||||
int);
|
||||
static bits_t *getkey_shell_cmd(const char *, struct keygen *, size_t);
|
||||
|
@ -337,6 +343,11 @@ getkey(const char *dev, struct keygen *kg, size_t len)
|
|||
case KEYGEN_URANDOMKEY:
|
||||
tmp = getkey_randomkey(dev, kg, len, 0);
|
||||
break;
|
||||
#ifdef HAVE_ARGON2
|
||||
case KEYGEN_ARGON2ID:
|
||||
tmp = getkey_argon2id(dev, kg, len);
|
||||
break;
|
||||
#endif
|
||||
case KEYGEN_PKCS5_PBKDF2_SHA1:
|
||||
tmp = getkey_pkcs5_pbkdf2(dev, kg, len, 0);
|
||||
break;
|
||||
|
@ -454,6 +465,40 @@ getkey_pkcs5_pbkdf2(const char *target, struct keygen *kg, size_t keylen,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ARGON2
|
||||
static bits_t *
|
||||
getkey_argon2id(const char *target, struct keygen *kg, size_t keylen)
|
||||
{
|
||||
bits_t *ret;
|
||||
char *passp;
|
||||
char buf[1024];
|
||||
uint8_t raw[256];
|
||||
int err;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s's passphrase%s:", target,
|
||||
pflag & PFLAG_GETPASS_ECHO ? " (echo)" : "");
|
||||
passp = maybe_getpass(buf);
|
||||
if ((err = argon2_hash(kg->kg_iterations, kg->kg_memory,
|
||||
kg->kg_parallelism,
|
||||
passp, strlen(passp),
|
||||
bits_getbuf(kg->kg_salt),
|
||||
BITS2BYTES(bits_len(kg->kg_salt)),
|
||||
raw, sizeof(raw),
|
||||
NULL, 0,
|
||||
Argon2_id, kg->kg_version)) != ARGON2_OK) {
|
||||
warnx("failed to generate Argon2id key, error code %d", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = bits_new(raw, keylen);
|
||||
kg->kg_key = bits_dup(ret);
|
||||
explicit_memset(passp, 0, strlen(passp));
|
||||
explicit_memset(raw, 0, sizeof(raw));
|
||||
free(passp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*ARGSUSED*/
|
||||
static bits_t *
|
||||
getkey_shell_cmd(const char *target, struct keygen *kg, size_t keylen)
|
||||
|
@ -606,8 +651,9 @@ configure(int argc, char **argv, struct params *inparams, int flags)
|
|||
for (kg = p->keygen;
|
||||
(pflag & PFLAG_GETPASS_MASK) && kg;
|
||||
kg = kg->next)
|
||||
if ((kg->kg_method == KEYGEN_PKCS5_PBKDF2_SHA1) ||
|
||||
(kg->kg_method == KEYGEN_PKCS5_PBKDF2_OLD )) {
|
||||
if (kg->kg_method == KEYGEN_ARGON2ID ||
|
||||
kg->kg_method == KEYGEN_PKCS5_PBKDF2_SHA1 ||
|
||||
kg->kg_method == KEYGEN_PKCS5_PBKDF2_OLD) {
|
||||
loop = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -984,22 +1030,39 @@ static int
|
|||
verify_reenter(struct params *p)
|
||||
{
|
||||
struct keygen *kg;
|
||||
bits_t *orig_key, *key;
|
||||
bits_t *orig_key, *key = NULL;
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
for (kg = p->keygen; kg && !ret; kg = kg->next) {
|
||||
if ((kg->kg_method != KEYGEN_PKCS5_PBKDF2_SHA1) &&
|
||||
(kg->kg_method != KEYGEN_PKCS5_PBKDF2_OLD ))
|
||||
if (kg->kg_method != KEYGEN_ARGON2ID &&
|
||||
kg->kg_method != KEYGEN_PKCS5_PBKDF2_SHA1 &&
|
||||
kg->kg_method != KEYGEN_PKCS5_PBKDF2_OLD)
|
||||
continue;
|
||||
|
||||
orig_key = kg->kg_key;
|
||||
kg->kg_key = NULL;
|
||||
|
||||
/* add a compat flag till the _OLD method goes away */
|
||||
switch (kg->kg_method) {
|
||||
#ifdef HAVE_ARGON2
|
||||
case KEYGEN_ARGON2ID:
|
||||
key = getkey_argon2id("re-enter device", kg,
|
||||
bits_len(orig_key));
|
||||
break;
|
||||
#endif
|
||||
case KEYGEN_PKCS5_PBKDF2_SHA1:
|
||||
key = getkey_pkcs5_pbkdf2("re-enter device", kg,
|
||||
bits_len(orig_key),
|
||||
kg->kg_method == KEYGEN_PKCS5_PBKDF2_OLD);
|
||||
bits_len(orig_key), 0);
|
||||
break;
|
||||
case KEYGEN_PKCS5_PBKDF2_OLD:
|
||||
key = getkey_pkcs5_pbkdf2("re-enter device", kg,
|
||||
bits_len(orig_key), 1);
|
||||
break;
|
||||
default:
|
||||
warnx("unsupported keygen method");
|
||||
kg->kg_key = orig_key;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = !bits_match(key, orig_key);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
%{
|
||||
/* $NetBSD: cgdlex.l,v 1.5 2009/10/29 14:49:03 christos Exp $ */
|
||||
/* $NetBSD: cgdlex.l,v 1.6 2021/11/22 14:34:35 nia Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: cgdlex.l,v 1.5 2009/10/29 14:49:03 christos Exp $");
|
||||
__RCSID("$NetBSD: cgdlex.l,v 1.6 2021/11/22 14:34:35 nia Exp $");
|
||||
#endif
|
||||
|
||||
#include <err.h>
|
||||
|
@ -98,6 +98,9 @@ verify_method { RETTOKEN(VERIFY_METHOD); }
|
|||
keygen { RETTOKEN(KEYGEN); }
|
||||
salt { RETTOKEN(SALT); }
|
||||
iterations { RETTOKEN(ITERATIONS); }
|
||||
memory { RETTOKEN(MEMORY); }
|
||||
parallelism { RETTOKEN(PARALLELISM); }
|
||||
version { RETTOKEN(VERSION); }
|
||||
key { RETTOKEN(KEY); }
|
||||
cmd { RETTOKEN(CMD); }
|
||||
keygen_method { RETTOKEN(KEYGEN_METHOD); }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
%{
|
||||
/* $NetBSD: cgdparse.y,v 1.5 2008/07/17 16:24:55 drochner Exp $ */
|
||||
/* $NetBSD: cgdparse.y,v 1.6 2021/11/22 14:34:35 nia Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: cgdparse.y,v 1.5 2008/07/17 16:24:55 drochner Exp $");
|
||||
__RCSID("$NetBSD: cgdparse.y,v 1.6 2021/11/22 14:34:35 nia Exp $");
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -67,7 +67,7 @@ static struct params *yy_global_params;
|
|||
%token <string> STRINGLIT
|
||||
|
||||
%token <token> ALGORITHM KEYLENGTH IVMETHOD VERIFY_METHOD
|
||||
%token <token> KEYGEN SALT ITERATIONS KEY CMD
|
||||
%token <token> KEYGEN SALT ITERATIONS MEMORY PARALLELISM VERSION KEY CMD
|
||||
|
||||
%token EOL
|
||||
|
||||
|
@ -99,6 +99,9 @@ kgvars: /* empty */ { $$ = NULL; }
|
|||
|
||||
kgvar: SALT bits EOL { $$ = keygen_salt($2); }
|
||||
| ITERATIONS INTEGER EOL { $$ = keygen_iterations($2); }
|
||||
| MEMORY INTEGER EOL { $$ = keygen_memory($2); }
|
||||
| PARALLELISM INTEGER EOL { $$ = keygen_parallelism($2); }
|
||||
| VERSION INTEGER EOL { $$ = keygen_version($2); }
|
||||
| KEY bits EOL { $$ = keygen_key($2); }
|
||||
| CMD stringlit EOL { $$ = keygen_cmd($2); }
|
||||
| EOL { $$ = NULL; }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: params.c,v 1.31 2021/06/03 15:40:27 prlw1 Exp $ */
|
||||
/* $NetBSD: params.c,v 1.32 2021/11/22 14:34:35 nia Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: params.c,v 1.31 2021/06/03 15:40:27 prlw1 Exp $");
|
||||
__RCSID("$NetBSD: params.c,v 1.32 2021/11/22 14:34:35 nia Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -45,6 +45,11 @@ __RCSID("$NetBSD: params.c,v 1.31 2021/06/03 15:40:27 prlw1 Exp $");
|
|||
#include <string.h>
|
||||
#include <util.h>
|
||||
|
||||
#ifdef HAVE_ARGON2
|
||||
#include <argon2.h>
|
||||
#include "argon2_utils.h"
|
||||
#endif
|
||||
|
||||
#include "params.h"
|
||||
#include "pkcs5_pbkdf2.h"
|
||||
#include "utils.h"
|
||||
|
@ -314,6 +319,9 @@ keygen_new(void)
|
|||
kg = emalloc(sizeof(*kg));
|
||||
kg->kg_method = KEYGEN_UNKNOWN;
|
||||
kg->kg_iterations = (size_t)-1;
|
||||
kg->kg_memory = (size_t)-1;
|
||||
kg->kg_parallelism = (size_t)-1;
|
||||
kg->kg_version = (size_t)-1;
|
||||
kg->kg_salt = NULL;
|
||||
kg->kg_key = NULL;
|
||||
kg->kg_cmd = NULL;
|
||||
|
@ -346,6 +354,34 @@ keygen_verify(const struct keygen *kg)
|
|||
if (!kg)
|
||||
return 1;
|
||||
switch (kg->kg_method) {
|
||||
#ifdef HAVE_ARGON2
|
||||
case KEYGEN_ARGON2ID:
|
||||
if (kg->kg_iterations == (size_t)-1) {
|
||||
warnx("keygen argon2id must provide `iterations'");
|
||||
return 0;
|
||||
}
|
||||
if (kg->kg_memory == (size_t)-1) {
|
||||
warnx("keygen argon2id must provide `memory'");
|
||||
return 0;
|
||||
}
|
||||
if (kg->kg_parallelism == (size_t)-1) {
|
||||
warnx("keygen argon2id must provide `parallelism'");
|
||||
return 0;
|
||||
}
|
||||
if (kg->kg_version == (size_t)-1) {
|
||||
warnx("keygen argon2id must provide `version'");
|
||||
return 0;
|
||||
}
|
||||
if (kg->kg_cmd)
|
||||
warnx("keygen argon2id does not need a `cmd'");
|
||||
if (kg->kg_key)
|
||||
warnx("keygen argon2id does not need a `key'");
|
||||
if (!kg->kg_salt) {
|
||||
warnx("keygen argon2id must provide a salt");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case KEYGEN_PKCS5_PBKDF2_OLD:
|
||||
if (kg->kg_iterations == (size_t)-1) {
|
||||
warnx("keygen pkcs5_pbkdf2 must provide `iterations'");
|
||||
|
@ -445,6 +481,14 @@ keygen_filldefaults(struct keygen *kg, size_t keylen)
|
|||
case KEYGEN_URANDOMKEY:
|
||||
case KEYGEN_SHELL_CMD:
|
||||
break;
|
||||
#ifdef HAVE_ARGON2
|
||||
case KEYGEN_ARGON2ID:
|
||||
kg->kg_version = ARGON2_VERSION_NUMBER;
|
||||
kg->kg_salt = bits_getrandombits(DEFAULT_SALTLEN, 1);
|
||||
argon2id_calibrate(BITS2BYTES(keylen), DEFAULT_SALTLEN,
|
||||
&kg->kg_iterations, &kg->kg_memory, &kg->kg_parallelism);
|
||||
break;
|
||||
#endif
|
||||
case KEYGEN_PKCS5_PBKDF2_OLD:
|
||||
case KEYGEN_PKCS5_PBKDF2_SHA1:
|
||||
kg->kg_salt = bits_getrandombits(DEFAULT_SALTLEN, 1);
|
||||
|
@ -488,6 +532,15 @@ keygen_combine(struct keygen *kg1, struct keygen *kg2)
|
|||
if (kg2->kg_iterations != (size_t)-1 && kg2->kg_iterations > 0)
|
||||
kg1->kg_iterations = kg2->kg_iterations;
|
||||
|
||||
if (kg2->kg_memory != (size_t)-1 && kg2->kg_memory > 0)
|
||||
kg1->kg_memory = kg2->kg_memory;
|
||||
|
||||
if (kg2->kg_parallelism != (size_t)-1 && kg2->kg_parallelism > 0)
|
||||
kg1->kg_parallelism = kg2->kg_parallelism;
|
||||
|
||||
if (kg2->kg_version != (size_t)-1 && kg2->kg_version > 0)
|
||||
kg1->kg_version = kg2->kg_version;
|
||||
|
||||
if (kg2->kg_salt)
|
||||
bits_assign(&kg1->kg_salt, kg2->kg_salt);
|
||||
|
||||
|
@ -506,6 +559,10 @@ keygen_method(string_t *in)
|
|||
struct keygen *kg = keygen_new();
|
||||
const char *kgm = string_tocharstar(in);
|
||||
|
||||
#ifdef HAVE_ARGON2
|
||||
if (!strcmp("argon2id", kgm))
|
||||
kg->kg_method = KEYGEN_ARGON2ID;
|
||||
#endif
|
||||
if (!strcmp("pkcs5_pbkdf2", kgm))
|
||||
kg->kg_method = KEYGEN_PKCS5_PBKDF2_OLD;
|
||||
if (!strcmp("pkcs5_pbkdf2/sha1", kgm))
|
||||
|
@ -551,6 +608,33 @@ keygen_iterations(size_t in)
|
|||
return kg;
|
||||
}
|
||||
|
||||
struct keygen *
|
||||
keygen_memory(size_t in)
|
||||
{
|
||||
struct keygen *kg = keygen_new();
|
||||
|
||||
kg->kg_memory = in;
|
||||
return kg;
|
||||
}
|
||||
|
||||
struct keygen *
|
||||
keygen_parallelism(size_t in)
|
||||
{
|
||||
struct keygen *kg = keygen_new();
|
||||
|
||||
kg->kg_parallelism = in;
|
||||
return kg;
|
||||
}
|
||||
|
||||
struct keygen *
|
||||
keygen_version(size_t in)
|
||||
{
|
||||
struct keygen *kg = keygen_new();
|
||||
|
||||
kg->kg_version = in;
|
||||
return kg;
|
||||
}
|
||||
|
||||
void
|
||||
keygen_addlist(struct keygen **l, struct keygen *e)
|
||||
{
|
||||
|
@ -743,6 +827,17 @@ keygen_fput(struct keygen *kg, int ts, FILE *f)
|
|||
case KEYGEN_URANDOMKEY:
|
||||
(void)fprintf(f, "urandomkey;\n");
|
||||
break;
|
||||
#ifdef HAVE_ARGON2
|
||||
case KEYGEN_ARGON2ID:
|
||||
(void)fprintf(f, "argon2id {\n");
|
||||
print_kvpair_int(f, ts, "iterations", kg->kg_iterations);
|
||||
print_kvpair_int(f, ts, "memory", kg->kg_memory);
|
||||
print_kvpair_int(f, ts, "parallelism", kg->kg_parallelism);
|
||||
print_kvpair_int(f, ts, "version", kg->kg_version);
|
||||
print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt);
|
||||
(void)fprintf(f, "};\n");
|
||||
break;
|
||||
#endif
|
||||
case KEYGEN_PKCS5_PBKDF2_OLD:
|
||||
(void)fprintf(f, "pkcs5_pbkdf2 {\n");
|
||||
print_kvpair_int(f, ts, "iterations", kg->kg_iterations);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: params.h,v 1.11 2014/12/14 12:31:39 mlelstv Exp $ */
|
||||
/* $NetBSD: params.h,v 1.12 2021/11/22 14:34:35 nia Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -37,6 +37,9 @@
|
|||
struct keygen {
|
||||
int kg_method;
|
||||
size_t kg_iterations;
|
||||
size_t kg_memory; /* only used for Argon2 */
|
||||
size_t kg_parallelism; /* only used for Argon2 */
|
||||
size_t kg_version; /* only used for Argon2 */
|
||||
bits_t *kg_salt;
|
||||
bits_t *kg_key;
|
||||
string_t *kg_cmd;
|
||||
|
@ -63,6 +66,7 @@ struct params {
|
|||
#define KEYGEN_URANDOMKEY 0x4
|
||||
#define KEYGEN_PKCS5_PBKDF2_SHA1 0x5
|
||||
#define KEYGEN_SHELL_CMD 0x6
|
||||
#define KEYGEN_ARGON2ID 0x7
|
||||
|
||||
/* verification methods */
|
||||
|
||||
|
@ -108,6 +112,9 @@ struct keygen *keygen_method(string_t *);
|
|||
struct keygen *keygen_set_method(struct keygen *, string_t *);
|
||||
struct keygen *keygen_salt(bits_t *);
|
||||
struct keygen *keygen_iterations(size_t);
|
||||
struct keygen *keygen_memory(size_t);
|
||||
struct keygen *keygen_parallelism(size_t);
|
||||
struct keygen *keygen_version(size_t);
|
||||
struct keygen *keygen_key(bits_t *);
|
||||
struct keygen *keygen_cmd(string_t *);
|
||||
|
||||
|
|
Loading…
Reference in New Issue