Module Name:    src
Committed By:   nia
Date:           Tue Oct 12 13:24:00 UTC 2021

Modified Files:
        src/lib/libcrypt: crypt-argon2.c crypt.h pw_gensalt.c util.c
        src/tests/lib/libcrypt: t_crypt.c

Log Message:
crypt(3): Make Argon2 implementation match the reference impl by
making sure input salts are decoded as base64.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/lib/libcrypt/crypt-argon2.c \
    src/lib/libcrypt/crypt.h
cvs rdiff -u -r1.9 -r1.10 src/lib/libcrypt/pw_gensalt.c
cvs rdiff -u -r1.1 -r1.2 src/lib/libcrypt/util.c
cvs rdiff -u -r1.4 -r1.5 src/tests/lib/libcrypt/t_crypt.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libcrypt/crypt-argon2.c
diff -u src/lib/libcrypt/crypt-argon2.c:1.5 src/lib/libcrypt/crypt-argon2.c:1.6
--- src/lib/libcrypt/crypt-argon2.c:1.5	Tue Oct 12 12:11:04 2021
+++ src/lib/libcrypt/crypt-argon2.c	Tue Oct 12 13:24:00 2021
@@ -7,6 +7,7 @@
 #include <pwd.h>
 #include <errno.h>
 #include <argon2.h>
+#include <resolv.h> /* for b64_pton... */
 
 #include <err.h>
 #include "crypt.h"
@@ -31,32 +32,6 @@
 #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 */
@@ -152,7 +127,7 @@ static int decode_option(argon2_context 
 
 	a = strsep(&inp, "$");
 
-	snprintf((char *)ctx->salt, ctx->saltlen, "%s", a);
+	b64_pton(a, ctx->salt, ctx->saltlen);
 
 	a = strsep(&inp, "$");
 
@@ -196,10 +171,7 @@ __crypt_argon2(const char *pw, const cha
 	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));
+	explicit_memset(rbuf, 0, sizeof(rbuf));
 
 	/* we use static buffers to avoid allocation */
 	/* and easier cleanup */
@@ -242,18 +214,10 @@ __crypt_argon2(const char *pw, const cha
 	/* skip over '$' */
 	blkp++;
 
-	/* we don't use encoded here because it base64 encodes salt */
-	/* same encoding format as argon2 api, but with original salt */
-	snprintf(rbuf, sizeof(rbuf)-1, "$%s$v=%d$m=%d,t=%d,p=%d$%s$%s",
-			argon2_type2string(atype,0),
-			ctx.version,
-			ctx.m_cost,
-			ctx.t_cost,
-			ctx.threads,
-			ctx.salt,
-			blkp);
+	memcpy(rbuf, encodebuf, sizeof(encodebuf));
 
 	/* clear buffers */
+	explicit_memset(ebuf, 0, sizeof(ebuf));
 	explicit_memset(encodebuf, 0, sizeof(encodebuf));
 	explicit_memset(saltbuf, 0, sizeof(saltbuf));
 	explicit_memset(pwdbuf, 0, sizeof(pwdbuf));
Index: src/lib/libcrypt/crypt.h
diff -u src/lib/libcrypt/crypt.h:1.5 src/lib/libcrypt/crypt.h:1.6
--- src/lib/libcrypt/crypt.h:1.5	Mon Oct 21 02:36:48 2019
+++ src/lib/libcrypt/crypt.h	Tue Oct 12 13:24:00 2021
@@ -1,6 +1,9 @@
 /*
- * $NetBSD: crypt.h,v 1.5 2019/10/21 02:36:48 jhigh Exp $
+ * $NetBSD: crypt.h,v 1.6 2021/10/12 13:24:00 nia Exp $
  */
+
+#define crypt_private     __attribute__((__visibility__("hidden")))
+
 char	*__md5crypt(const char *pw, const char *salt);	/* XXX */
 char *__bcrypt(const char *, const char *);	/* XXX */
 char *__crypt_sha1(const char *pw, const char *salt);
@@ -22,5 +25,7 @@ int __gensalt_new(char *salt, size_t sal
 int __gensalt_md5(char *salt, size_t saltsiz, const char *option);
 int __gensalt_sha1(char *salt, size_t saltsiz, const char *option);
 
+crypt_private int getnum(const char *, size_t *);
+
 #define SHA1_MAGIC "$sha1$"
 #define SHA1_SIZE 20

Index: src/lib/libcrypt/pw_gensalt.c
diff -u src/lib/libcrypt/pw_gensalt.c:1.9 src/lib/libcrypt/pw_gensalt.c:1.10
--- src/lib/libcrypt/pw_gensalt.c:1.9	Thu May 14 08:34:19 2020
+++ src/lib/libcrypt/pw_gensalt.c	Tue Oct 12 13:24:00 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: pw_gensalt.c,v 1.9 2020/05/14 08:34:19 msaitoh Exp $	*/
+/*	$NetBSD: pw_gensalt.c,v 1.10 2021/10/12 13:24:00 nia Exp $	*/
 
 /*
  * Copyright 1997 Niels Provos <pro...@physnet.uni-hamburg.de>
@@ -34,7 +34,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: pw_gensalt.c,v 1.9 2020/05/14 08:34:19 msaitoh Exp $");
+__RCSID("$NetBSD: pw_gensalt.c,v 1.10 2021/10/12 13:24:00 nia Exp $");
 #endif /* not lint */
 
 #include <sys/syslimits.h>
@@ -81,30 +81,6 @@ static const struct pw_salt {
 	{ NULL, NULL }
 };
 
-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;
-}
-
 int
 /*ARGSUSED2*/
 __gensalt_old(char *salt, size_t saltsiz, const char *option)

Index: src/lib/libcrypt/util.c
diff -u src/lib/libcrypt/util.c:1.1 src/lib/libcrypt/util.c:1.2
--- src/lib/libcrypt/util.c:1.1	Fri Jul  2 00:05:23 2004
+++ src/lib/libcrypt/util.c	Tue Oct 12 13:24:00 2021
@@ -1,17 +1,75 @@
+/*	$NetBSD: util.c,v 1.2 2021/10/12 13:24:00 nia Exp $	*/
+/*
+ * Copyright 1997 Niels Provos <pro...@physnet.uni-hamburg.de>
+ * All rights reserved.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Niels Provos.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/cdefs.h>
 #if !defined(lint)
-__RCSID("$NetBSD: util.c,v 1.1 2004/07/02 00:05:23 sjg Exp $");
+__RCSID("$NetBSD: util.c,v 1.2 2021/10/12 13:24:00 nia Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
 
 #include "crypt.h"
 
 static const unsigned char itoa64[] =		/* 0 ... 63 => ascii - 64 */
 	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
+crypt_private 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;
+}
+
 void
-__crypt_to64(char *s, u_int32_t v, int n)
+__crypt_to64(char *s, uint32_t v, int n)
 {
 
 	while (--n >= 0) {

Index: src/tests/lib/libcrypt/t_crypt.c
diff -u src/tests/lib/libcrypt/t_crypt.c:1.4 src/tests/lib/libcrypt/t_crypt.c:1.5
--- src/tests/lib/libcrypt/t_crypt.c:1.4	Tue Oct 12 10:52:40 2021
+++ src/tests/lib/libcrypt/t_crypt.c	Tue Oct 12 13:24:00 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: t_crypt.c,v 1.4 2021/10/12 10:52:40 nia Exp $ */
+/* $NetBSD: t_crypt.c,v 1.5 2021/10/12 13:24:00 nia Exp $ */
 
 /*
  * This version is derived from the original implementation of FreeSec
@@ -61,7 +61,7 @@
  *	by now.	 The code requires a 32-bit integer type, though.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_crypt.c,v 1.4 2021/10/12 10:52:40 nia Exp $");
+__RCSID("$NetBSD: t_crypt.c,v 1.5 2021/10/12 13:24:00 nia Exp $");
 
 #include <atf-c.h>
 #include <stdio.h>
@@ -116,20 +116,20 @@ static const struct {
  * NOTE: Upstream Argon2 uses base64-encoded salts, whereas NetBSD doesn't...
  */
 /* Argon2i version number 16 */
-/* 33 */	{ "$argon2i$v=16$m=256,t=2,p=1$somesalt$/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY", "password" },
-/* 34 */	{ "$argon2i$v=16$m=65536,t=1,p=1$somesalt$gWMFUrjzsfSM2xmSxMZ4ZD1JCytetP9sSzQ4tWIXJLI", "password" },
-/* 35 */	{ "$argon2i$v=16$m=65536,t=2,p=1$diffsalt$eaEDuQ/orvhXDLMfyLIiWXeJFvgza3vaw4kladTxxJc", "password" },
-/* 36 */	{ "$argon2i$v=16$m=65536,t=2,p=1$somesalt$6ckCB0tnVFMaOgvlGeW69ASzDOabPwGsO/ISKZYBCaM", "differentpassword" },
+/* 33 */	{ "$argon2i$v=16$m=256,t=2,p=1$c29tZXNhbHQ$/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY", "password" },
+/* 34 */	{ "$argon2i$v=16$m=65536,t=1,p=1$c29tZXNhbHQ$gWMFUrjzsfSM2xmSxMZ4ZD1JCytetP9sSzQ4tWIXJLI", "password" },
+/* 35 */	{ "$argon2i$v=16$m=65536,t=2,p=1$ZGlmZnNhbHQ$eaEDuQ/orvhXDLMfyLIiWXeJFvgza3vaw4kladTxxJc", "password" },
+/* 36 */	{ "$argon2i$v=16$m=65536,t=2,p=1$c29tZXNhbHQ$6ckCB0tnVFMaOgvlGeW69ASzDOabPwGsO/ISKZYBCaM", "differentpassword" },
 /* Argon2i version number 19 */
-/* 37 */	{ "$argon2i$v=19$m=256,t=2,p=1$somesalt$iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8", "password" },
-/* 38 */	{ "$argon2i$v=19$m=65536,t=1,p=1$somesalt$0WgHXE2YXhPr6uVgz4uUw7XYoWxRkWtvSsLaOsEbvs8", "password" },
-/* 39 */	{ "$argon2i$v=19$m=65536,t=2,p=1$diffsalt$sDV8zPvvkfOGCw26RHsjSMvv7K2vmQq/6cxAcmxSEnE", "password" },
-/* 40 */	{ "$argon2i$v=19$m=65536,t=2,p=1$somesalt$FK6NoBr+qHAMI1jc73xTWNkCEoK9iGY6RWL1n7dNIu4", "differentpassword" },
+/* 37 */	{ "$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ$iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8", "password" },
+/* 38 */	{ "$argon2i$v=19$m=65536,t=1,p=1$c29tZXNhbHQ$0WgHXE2YXhPr6uVgz4uUw7XYoWxRkWtvSsLaOsEbvs8", "password" },
+/* 39 */	{ "$argon2i$v=19$m=65536,t=2,p=1$ZGlmZnNhbHQ$sDV8zPvvkfOGCw26RHsjSMvv7K2vmQq/6cxAcmxSEnE", "password" },
+/* 40 */	{ "$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ$FK6NoBr+qHAMI1jc73xTWNkCEoK9iGY6RWL1n7dNIu4", "differentpassword" },
 /* Argon2id version number 19 */
-/* 41 */	{ "$argon2id$v=19$m=256,t=2,p=2$somesalt$bQk8UB/VmZZF4Oo79iDXuL5/0ttZwg2f/5U52iv1cDc", "password" },
-/* 42 */	{ "$argon2id$v=19$m=65536,t=4,p=1$somesalt$kCXUjmjvc5XMqQedpMTsOv+zyJEf5PhtGiUghW9jFyw", "password" },
-/* 43 */	{ "$argon2id$v=19$m=65536,t=2,p=1$diffsalt$vfMrBczELrFdWP0ZsfhWsRPaHppYdP3MVEMIVlqoFBw", "password" },
-/* 44 */	{ "$argon2id$v=19$m=65536,t=2,p=1$somesalt$C4TWUs9rDEvq7w3+J4umqA32aWKB1+DSiRuBfYxFj94", "differentpassword" },
+/* 41 */	{ "$argon2id$v=19$m=256,t=2,p=2$c29tZXNhbHQ$bQk8UB/VmZZF4Oo79iDXuL5/0ttZwg2f/5U52iv1cDc", "password" },
+/* 42 */	{ "$argon2id$v=19$m=65536,t=4,p=1$c29tZXNhbHQ$kCXUjmjvc5XMqQedpMTsOv+zyJEf5PhtGiUghW9jFyw", "password" },
+/* 43 */	{ "$argon2id$v=19$m=65536,t=2,p=1$ZGlmZnNhbHQ$vfMrBczELrFdWP0ZsfhWsRPaHppYdP3MVEMIVlqoFBw", "password" },
+/* 44 */	{ "$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ$C4TWUs9rDEvq7w3+J4umqA32aWKB1+DSiRuBfYxFj94", "differentpassword" },
 #endif
 /* 45 */	{ NULL, NULL }
 };

Reply via email to