Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/pwhash adding argon2 support to libcrypt. argon2 use...
details: https://anonhg.NetBSD.org/src/rev/cef07fae0e3f
branches: trunk
changeset: 966247:cef07fae0e3f
user: jhigh <jhigh%NetBSD.org@localhost>
date: Mon Oct 21 02:36:48 2019 +0000
description:
adding argon2 support to libcrypt. argon2 user authentication now
available via MKARGON2=yes (3 variants supported; argon2id recommended)
before using, please read argon2 paper at
https://github.com/P-H-C/phc-winner-argon2
diffstat:
external/apache2/argon2/lib/libargon2/Makefile | 10 +-
external/apache2/argon2/usr.bin/argon2/Makefile | 11 +-
lib/libcrypt/Makefile | 14 +-
lib/libcrypt/crypt-argon2.c | 254 ++++++++++++++++++++++++
lib/libcrypt/crypt.3 | 42 ++-
lib/libcrypt/crypt.c | 17 +-
lib/libcrypt/crypt.h | 9 +-
lib/libcrypt/pw_gensalt.c | 132 ++++++++++++-
usr.bin/pwhash/Makefile | 6 +-
usr.bin/pwhash/pwhash.1 | 31 ++-
usr.bin/pwhash/pwhash.c | 46 ++++-
11 files changed, 524 insertions(+), 48 deletions(-)
diffs (truncated from 826 to 300 lines):
diff -r 96aeb0c8f0aa -r cef07fae0e3f external/apache2/argon2/lib/libargon2/Makefile
--- a/external/apache2/argon2/lib/libargon2/Makefile Sun Oct 20 23:47:14 2019 +0000
+++ b/external/apache2/argon2/lib/libargon2/Makefile Mon Oct 21 02:36:48 2019 +0000
@@ -12,15 +12,7 @@
LIB= argon2
SRCS= argon2.c core.c blake2b.c thread.c encoding.c ref.c
-
-CPPFLAGS= -std=c89 -O3 -Wall -g -I../../dist/phc-winner-argon2/include -Isrc -shared -fPIC
-
-.ifdef NO_THREADS
-CPPFLAGS += -DARGON2_NO_THREADS
-.else
-CPPFLAGS += -pthread
-LDADD+=-lpthread
-.endif
+CPPFLAGS= -std=c89 -O3 -Wall -g -I../../dist/phc-winner-argon2/include -Isrc -fPIC -DARGON2_NO_THREADS
OPTTARGET ?= native
OPTTEST := $(shell $(CC) -Iinclude -Isrc -march=$(OPTTARGET) src/opt.c -c \
diff -r 96aeb0c8f0aa -r cef07fae0e3f external/apache2/argon2/usr.bin/argon2/Makefile
--- a/external/apache2/argon2/usr.bin/argon2/Makefile Sun Oct 20 23:47:14 2019 +0000
+++ b/external/apache2/argon2/usr.bin/argon2/Makefile Mon Oct 21 02:36:48 2019 +0000
@@ -10,16 +10,7 @@
SRCS= argon2.c core.c blake2b.c thread.c encoding.c ref.c
SRCS+= run.c
-.ifdef NO_THREADS
-CPPFLAGS += -DARGON2_NO_THREADS
-.else
-CPPFLAGS += -pthread
-LDADD+=-lpthread
-.endif
-
-CPPFLAGS+= -std=c89 -O3 -Wall -g -I../../dist/phc-winner-argon2/include -Isrc #-shared -fPIC
-#LDADD+= -L${LIBARGON2} -largon2
-#DPADD+= ${LIBARGON2_SD}
+CPPFLAGS+= -DARGON2_NO_THREADS -std=c89 -O3 -Wall -g -I../../dist/phc-winner-argon2/include -Isrc
MAN=argon2.1
diff -r 96aeb0c8f0aa -r cef07fae0e3f lib/libcrypt/Makefile
--- a/lib/libcrypt/Makefile Sun Oct 20 23:47:14 2019 +0000
+++ b/lib/libcrypt/Makefile Mon Oct 21 02:36:48 2019 +0000
@@ -1,12 +1,24 @@
-# $NetBSD: Makefile,v 1.25 2013/08/10 18:42:29 dholland Exp $
+# $NetBSD: Makefile,v 1.26 2019/10/21 02:36:48 jhigh Exp $
+
+.include <bsd.own.mk>
USE_SHLIBDIR= yes
+.if (defined(MKARGON2) && ${MKARGON2} != "no")
+HAVE_ARGON2=1
+.endif
+
LIB= crypt
SRCS= crypt.c md5crypt.c bcrypt.c crypt-sha1.c util.c pw_gensalt.c
SRCS+= hmac_sha1.c
+.if defined(HAVE_ARGON2)
+SRCS+= crypt-argon2.c
+CFLAGS+= -DHAVE_ARGON2 -I../../external/apache2/argon2/dist/phc-winner-argon2/include/
+LDADD+= -largon2
+.endif
+
WARNS?= 5
MAN= crypt.3
diff -r 96aeb0c8f0aa -r cef07fae0e3f lib/libcrypt/crypt-argon2.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libcrypt/crypt-argon2.c Mon Oct 21 02:36:48 2019 +0000
@@ -0,0 +1,254 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <pwd.h>
+#include <errno.h>
+#include <argon2.h>
+
+#include <err.h>
+#include "crypt.h"
+
+/* defaults pulled from run.c */
+#define HASHLEN 32
+#define T_COST_DEF 3
+#define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */
+#define LANES_DEF 1
+#define THREADS_DEF 1
+#define OUTLEN_DEF 32
+#define MAX_PASS_LEN 128
+
+#define ARGON2_CONTEXT_INITIALIZER \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ T_COST_DEF, LOG_M_COST_DEF,\
+ LANES_DEF, THREADS_DEF, \
+ ARGON2_VERSION_NUMBER, 0, 0, ARGON2_DEFAULT_FLAGS}
+
+#define ARGON2_ARGON2_STR "argon2"
+#define ARGON2_ARGON2I_STR "argon2i"
+#define ARGON2_ARGON2D_STR "argon2d"
+#define ARGON2_ARGON2ID_STR "argon2id"
+
+/* getnum also declared in pw_getsalt.c */
+/* maybe move to util.h?? */
+static int
+getnum(const char *str, size_t *num)
+{
+ char *ep;
+ unsigned long rv;
+
+ if (str == NULL) {
+ *num = 0;
+ return 0;
+ }
+
+ rv = strtoul(str, &ep, 0);
+
+ if (str == ep || *ep) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (errno == ERANGE && rv == ULONG_MAX)
+ return -1;
+ *num = (size_t)rv;
+ return 0;
+}
+
+/* process params to argon2 */
+/* we don't force param order as input, */
+/* but we do provide the expected order to argon2 api */
+static int decode_option(argon2_context * ctx, argon2_type * atype, const char * option)
+{
+ size_t tmp=0;
+ char * in = 0,*inp;;
+ char * a=0;
+ char * p=0;
+ size_t sl;
+ int error=0;
+
+ in = (char *)strdup(option);
+ inp = in;
+
+ if (*inp == '$') inp++;
+
+ a = strsep(&inp, "$");
+
+ sl = strlen(a);
+
+ if (sl == strlen(ARGON2_ARGON2I_STR) &&
+ !(strcmp(ARGON2_ARGON2I_STR, a))) {
+ *atype=Argon2_i;
+ } else if (sl == strlen(ARGON2_ARGON2D_STR) &&
+ !(strcmp(ARGON2_ARGON2D_STR, a))) {
+ *atype=Argon2_d;
+ }
+ else if (sl == strlen(ARGON2_ARGON2ID_STR) &&
+ !(strcmp(ARGON2_ARGON2ID_STR, a))) {
+ *atype=Argon2_id;
+ } else { /* default to id, we assume simple mistake */
+ /* don't abandon yet */
+ *atype=Argon2_id;
+ }
+
+ a = strsep(&inp, "$");
+
+ if ((getnum(a, &tmp))<0) { /* on error, default to current */
+ /* should start thinking about aborting */
+ ctx->version = ARGON2_VERSION_NUMBER;
+ } else {
+ ctx->version = tmp;
+ }
+
+ a = strsep(&inp, "$");
+
+ /* parse labelled argon2 params */
+ /* m_cost (m)
+ * t_cost (t)
+ * threads (p)
+ */
+ while ((p = strsep(&a, ","))) {
+ switch (*p) {
+ case 'm':
+ p += strlen("m=");
+ if ((getnum(p, &tmp)) < 0) {
+ --error;
+ } else {
+ ctx->m_cost = tmp;
+ }
+ break;
+ case 't':
+ p += strlen("t=");
+ if ((getnum(p, &tmp)) < 0) {
+ --error;
+ } else {
+ ctx->t_cost = tmp;
+ }
+ break;
+ case 'p':
+ p += strlen("p=");
+ if ((getnum(p, &tmp)) < 0) {
+ --error;
+ } else {
+ ctx->threads = tmp;
+ }
+ break;
+ default:
+ return -1;
+
+ }
+ }
+
+ a = strsep(&inp, "$");
+
+ snprintf((char *)ctx->salt,ctx->saltlen, "%s", a);
+
+ a = strsep(&inp, "$");
+
+ if (*a) {
+ snprintf((char *)ctx->pwd,ctx->pwdlen, "%s", a);
+ } else {
+ /* don't care if passwd hash is missing */
+ /* if missing, most likely coming from */
+ /* pwhash or similar */
+ }
+
+ /* free our token buffer */
+ free(in);
+
+ /* 0 on success, <0 otherwise */
+ return error;
+}
+
+char *
+__crypt_argon2(const char *pw, const char * salt)
+{
+ /* we use the libargon2 api to generate */
+ /* return code */
+ int rc=0;
+ /* output buffer */
+ char ebuf[32];
+ /* ptr into argon2 encoded buffer */
+ char * blkp=0;
+ /* argon2 variable, default to id */
+ argon2_type atype = Argon2_id;
+ /* default to current argon2 version */
+ int version=ARGON2_VERSION_NUMBER;
+ /* argon2 context to collect params */
+ argon2_context ctx = ARGON2_CONTEXT_INITIALIZER;
+ /* argon2 encoded buffer */
+ char encodebuf[256];
+ /* argon2 salt buffer */
+ char saltbuf[128];
+ /* argon2 pwd buffer */
+ char pwdbuf[128];
+ /* returned static buffer */
+ static char rbuf[512];
+
+ /* clear buffers */
+ memset(encodebuf, 0, sizeof(encodebuf));
+ memset(saltbuf, 0, sizeof(saltbuf));
+ memset(pwdbuf, 0, sizeof(pwdbuf));
+ memset(rbuf, 0, sizeof(rbuf));
+
+ /* we use static buffers to avoid allocation */
+ /* and easier cleanup */
+ ctx.out = (uint8_t *)ebuf;
+ ctx.outlen = sizeof(ebuf);
+
+ ctx.out = (uint8_t *)encodebuf;
+ ctx.outlen = sizeof(encodebuf);
+
+ ctx.salt = (uint8_t *)saltbuf;
+ ctx.saltlen = sizeof(saltbuf);
+
+ ctx.pwd= (uint8_t *)pwdbuf;
+ ctx.pwdlen = sizeof(pwdbuf);
+
+ /* decode salt string to argon2 params */
+ /* argon2 context for param collection */
+ rc = decode_option(&ctx, &atype, salt);
+
+ if (rc < 0) {
+ /* unable to parse input params */
+ return 0;
+ }
+
+ rc = argon2_hash(ctx.t_cost, ctx.m_cost,
+ ctx.threads, pw, strlen(pw), ctx.salt, strlen((char*)ctx.salt),
+ ebuf, sizeof(ebuf), encodebuf, sizeof(encodebuf), atype, ctx.version);
+
+ if (rc != ARGON2_OK) {
+ fprintf(stderr, "Failed: %s\n", argon2_error_message(rc));
+ return 0;
+ }
Home |
Main Index |
Thread Index |
Old Index