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 } };