Index: include/unistd.h =================================================================== RCS file: /cvsroot/src/include/unistd.h,v retrieving revision 1.162 diff -u -r1.162 unistd.h --- include/unistd.h 15 Oct 2021 22:32:28 -0000 1.162 +++ include/unistd.h 12 Feb 2022 12:47:04 -0000 @@ -325,8 +325,15 @@ * Implementation-defined extensions */ #if defined(_NETBSD_SOURCE) +struct crypt_data { + int initialized; /* glibc compat */ + char __buf[512]; /* buffer returned by crypt_r */ +}; + + int acct(const char *); int closefrom(int); +char *crypt_r(const char *, const char *, struct crypt_data *); int des_cipher(const char *, char *, long, int); int des_setkey(const char *); int dup3(int, int, int); Index: lib/libcrypt/bcrypt.c =================================================================== RCS file: /cvsroot/src/lib/libcrypt/bcrypt.c,v retrieving revision 1.22 diff -u -r1.22 bcrypt.c --- lib/libcrypt/bcrypt.c 16 Oct 2021 10:53:33 -0000 1.22 +++ lib/libcrypt/bcrypt.c 12 Feb 2022 12:47:04 -0000 @@ -74,9 +74,9 @@ static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t); static void decode_base64(u_int8_t *, u_int16_t, const u_int8_t *); -crypt_private char *__bcrypt(const char *, const char *); /* XXX */ +/* crypt_private char *__bcrypt(const char *, const char *);*/ /* XXX */ -static char encrypted[_PASSWORD_LEN]; +/* static char encrypted[_PASSWORD_LEN]; */ static const u_int8_t Base64Code[] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; @@ -210,7 +210,7 @@ i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */ crypt_private char * -__bcrypt(const char *key, const char *salt) +__bcrypt(const char *key, const char *salt, struct crypt_data *data) { blf_ctx state; u_int32_t rounds, i, k; @@ -221,6 +221,8 @@ u_int32_t cdata[BCRYPT_BLOCKS]; int n; size_t len; + char *encrypted = data->__buf; + explicit_memset(data->__buf, 0, sizeof(data->__buf)); /* Discard "$" identifier */ salt++; Index: lib/libcrypt/crypt-argon2.c =================================================================== RCS file: /cvsroot/src/lib/libcrypt/crypt-argon2.c,v retrieving revision 1.15 diff -u -r1.15 crypt-argon2.c --- lib/libcrypt/crypt-argon2.c 22 Nov 2021 14:30:24 -0000 1.15 +++ lib/libcrypt/crypt-argon2.c 12 Feb 2022 12:47:04 -0000 @@ -360,7 +360,7 @@ } crypt_private char * -__crypt_argon2(const char *pw, const char * salt) +__crypt_argon2(const char *pw, const char * salt, struct crypt_data *data) { /* we use the libargon2 api to generate */ /* return code */ @@ -379,10 +379,10 @@ /* argon2 pwd buffer */ char pwdbuf[128]; /* returned static buffer */ - static char rbuf[512]; + /* static char rbuf[512]; */ /* clear buffers */ - explicit_memset(rbuf, 0, sizeof(rbuf)); + explicit_memset(data->__buf, 0, sizeof(data->__buf)); /* we use static buffers to avoid allocation */ /* and easier cleanup */ @@ -418,7 +418,7 @@ return NULL; } - memcpy(rbuf, encodebuf, sizeof(encodebuf)); + memcpy(data->__buf, encodebuf, sizeof(encodebuf)); /* clear buffers */ explicit_memset(ebuf, 0, sizeof(ebuf)); @@ -427,5 +427,5 @@ explicit_memset(pwdbuf, 0, sizeof(pwdbuf)); /* return encoded str */ - return rbuf; + return data->__buf; } Index: lib/libcrypt/crypt-sha1.c =================================================================== RCS file: /cvsroot/src/lib/libcrypt/crypt-sha1.c,v retrieving revision 1.10 diff -u -r1.10 crypt-sha1.c --- lib/libcrypt/crypt-sha1.c 29 Oct 2021 13:22:08 -0000 1.10 +++ lib/libcrypt/crypt-sha1.c 12 Feb 2022 12:47:04 -0000 @@ -107,12 +107,12 @@ * hmac key. */ crypt_private char * -__crypt_sha1 (const char *pw, const char *salt) +__crypt_sha1 (const char *pw, const char *salt, struct crypt_data *data) { static const char *magic = SHA1_MAGIC; static unsigned char hmac_buf[SHA1_SIZE]; - static char passwd[(2 * sizeof(SHA1_MAGIC)) + - CRYPT_SHA1_SALT_LENGTH + SHA1_SIZE]; + /* static char passwd[(2 * sizeof(SHA1_MAGIC)) + + CRYPT_SHA1_SALT_LENGTH + SHA1_SIZE]; */ const char *sp; char *ep; unsigned long ul; @@ -154,19 +154,19 @@ * Now get to work... * Prime the pump with */ - dl = snprintf(passwd, sizeof (passwd), "%.*s%s%u", + dl = snprintf(data->__buf, sizeof (data->__buf), "%.*s%s%u", sl, salt, magic, iterations); /* * Then hmac using as key, and repeat... */ - __hmac_sha1((unsigned char *)passwd, dl, pwu, pl, hmac_buf); + __hmac_sha1((unsigned char *)data->__buf, dl, pwu, pl, hmac_buf); for (i = 1; i < iterations; i++) { __hmac_sha1(hmac_buf, SHA1_SIZE, pwu, pl, hmac_buf); } /* Now output... */ - pl = snprintf(passwd, sizeof(passwd), "%s%u$%.*s$", + pl = snprintf(data->__buf, sizeof(data->__buf), "%s%u$%.*s$", magic, iterations, sl, salt); - ep = passwd + pl; + ep = data->__buf + pl; /* Every 3 bytes of hash gives 24 bits which is 4 base64 chars */ for (i = 0; i < SHA1_SIZE - 3; i += 3) { @@ -185,5 +185,5 @@ /* Don't leave anything around in vm they could use. */ explicit_memset(hmac_buf, 0, sizeof hmac_buf); - return passwd; + return data->__buf; } Index: lib/libcrypt/crypt.c =================================================================== RCS file: /cvsroot/src/lib/libcrypt/crypt.c,v retrieving revision 1.38 diff -u -r1.38 crypt.c --- lib/libcrypt/crypt.c 22 Feb 2020 10:29:17 -0000 1.38 +++ lib/libcrypt/crypt.c 12 Feb 2022 12:47:04 -0000 @@ -466,7 +466,8 @@ static C_block constdatablock; /* encryption constant */ -static char cryptresult[1+4+4+11+1]; /* encrypted result */ +/* static char cryptresult[1+4+4+11+1];*/ /* encrypted result */ +static struct crypt_data cryptresult; /* encrypted result */ /* * We match the behavior of UFC-crypt on systems where "char" is signed by @@ -545,7 +546,7 @@ * followed by an encryption produced by the "key" and "setting". */ static char * -__crypt(const char *key, const char *setting) +__crypt(const char *key, const char *setting, struct crypt_data *data) { char *encp; char scheme[12]; @@ -568,24 +569,24 @@ /* $2a$ found in bcrypt.c:encode_salt */ if (strcmp(scheme, "2a") == 0) { - return (__bcrypt(key, setting)); + return (__bcrypt(key, setting, data)); } else if (strcmp(scheme, "sha1") == 0) { /* $sha1$ found in crypt.h:SHA1_MAGIC */ - return (__crypt_sha1(key, setting)); + return (__crypt_sha1(key, setting, data)); } else if (strcmp(scheme, "1") == 0) { /* $1$ found in pw_gensalt.c:__gensalt_md5 */ - return (__md5crypt(key, setting)); + return (__md5crypt(key, setting, data)); #ifdef HAVE_ARGON2 /* explicit argon2 variant */ } else if (strcmp(scheme, "argon2id") == 0) { /* $argon2id$ found in pw_gensalt.c:__gensalt_argon2 */ - return (__crypt_argon2(key, setting)); + return (__crypt_argon2(key, setting, data)); } else if (strcmp(scheme, "argon2i") == 0) { /* $argon2i$ found in pw_gensalt.c:__gensalt_argon2 */ - return (__crypt_argon2(key, setting)); + return (__crypt_argon2(key, setting, data)); } else if (strcmp(scheme, "argon2d") == 0) { /* $argon2d$ found in pw_gensalt.c:__gensalt_argon2 */ - return (__crypt_argon2(key, setting)); + return (__crypt_argon2(key, setting, data)); #endif /* HAVE_ARGON2 */ } else { /* invalid scheme, including empty string */ @@ -594,6 +595,8 @@ } /* End non-DES handling */ + explicit_memset(data->__buf, 0, sizeof(data->__buf)); + for (i = 0; i < 8; i++) { if ((t = 2*(unsigned char)(*key)) != 0) key++; @@ -602,7 +605,7 @@ if (des_setkey((char *)keyblock.b)) return (NULL); - encp = &cryptresult[0]; + encp = data->__buf; switch (*setting) { case _PASSWORD_EFMT1: /* @@ -680,13 +683,13 @@ encp[3] = 0; - return (cryptresult); + return (data->__buf); } char * crypt(const char *key, const char *salt) { - char *res = __crypt(key, salt); + char *res = __crypt(key, salt, &cryptresult); if (res) return res; @@ -694,6 +697,13 @@ return __UNCONST(salt[0] == '*' && salt[1] == '0' ? "*1" : "*0"); } +char * +crypt_r(const char *key, const char *salt, struct crypt_data *data) +{ + return __crypt(key, salt, data); +} + + /* * The Key Schedule, filled in by des_setkey() or setkey(). */ Index: lib/libcrypt/crypt.h =================================================================== RCS file: /cvsroot/src/lib/libcrypt/crypt.h,v retrieving revision 1.8 diff -u -r1.8 crypt.h --- lib/libcrypt/crypt.h 16 Oct 2021 10:53:33 -0000 1.8 +++ lib/libcrypt/crypt.h 12 Feb 2022 12:47:04 -0000 @@ -2,17 +2,19 @@ * $NetBSD: crypt.h,v 1.8 2021/10/16 10:53:33 nia Exp $ */ +#include + #define crypt_private __attribute__((__visibility__("hidden"))) -crypt_private char *__md5crypt(const char *, const char *); /* XXX */ -crypt_private char *__bcrypt(const char *, const char *); /* XXX */ -crypt_private char *__crypt_sha1(const char *, const char *); +crypt_private char *__md5crypt(const char *, const char *, struct crypt_data *data); /* XXX */ +crypt_private char *__bcrypt(const char *, const char *, struct crypt_data *data); /* XXX */ +crypt_private char *__crypt_sha1(const char *, const char *, struct crypt_data *data); crypt_private unsigned int __crypt_sha1_iterations (unsigned int); crypt_private void __hmac_sha1(const unsigned char *, size_t, const unsigned char *, size_t, unsigned char *); #ifdef HAVE_ARGON2 -crypt_private char *__crypt_argon2(const char *, const char *); +crypt_private char *__crypt_argon2(const char *, const char *, struct crypt_data *data); crypt_private int __gensalt_argon2id(char *, size_t, const char *); crypt_private int __gensalt_argon2i(char *, size_t, const char *); crypt_private int __gensalt_argon2d(char *, size_t, const char *); Index: lib/libcrypt/md5crypt.c =================================================================== RCS file: /cvsroot/src/lib/libcrypt/md5crypt.c,v retrieving revision 1.15 diff -u -r1.15 md5crypt.c --- lib/libcrypt/md5crypt.c 16 Oct 2021 10:53:33 -0000 1.15 +++ lib/libcrypt/md5crypt.c 12 Feb 2022 12:47:04 -0000 @@ -37,9 +37,9 @@ * MD5 password encryption. */ crypt_private char * -__md5crypt(const char *pw, const char *salt) +__md5crypt(const char *pw, const char *salt, struct crypt_data *data) { - static char passwd[120], *p; + char *p; const char *sp, *ep; unsigned char final[16]; unsigned int i, sl, pwl; @@ -95,9 +95,9 @@ UPDATE(&ctx, (const unsigned char *)pw, 1); /* Now make the output string */ - memcpy(passwd, MD5_MAGIC, MD5_MAGIC_LEN); - strlcpy(passwd + MD5_MAGIC_LEN, sp, sl + 1); - strlcat(passwd, "$", sizeof(passwd)); + memcpy(data->__buf, MD5_MAGIC, MD5_MAGIC_LEN); + strlcpy(data->__buf + MD5_MAGIC_LEN, sp, sl + 1); + strlcat(data->__buf, "$", sizeof(data->__buf)); FINAL(final, &ctx); @@ -132,7 +132,7 @@ /* memset(&ctx1, 0, sizeof(ctx1)); done by MD5Final() */ - p = passwd + sl + MD5_MAGIC_LEN + 1; + p = data->__buf + sl + MD5_MAGIC_LEN + 1; l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; __crypt_to64(p,l,4); p += 4; l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; __crypt_to64(p,l,4); p += 4; @@ -144,5 +144,5 @@ /* Don't leave anything around in vm they could use. */ explicit_memset(final, 0, sizeof(final)); - return (passwd); + return (data->__buf); }