Skip to content

Commit

Permalink
Full crypt_newpass compat.
Browse files Browse the repository at this point in the history
This adds two depending parts: _PASSWORD_LEN for Linux and
timingsafe_bcmp for others.  The compat embeds bcrypt() and the
bcrypt_newhash() functions, but does not expose them.

It also fixes the strndup regression not to raise a warning on Linux and
an incorrect definition of _GNU_SOURCE instead of _XOPEN_SOURCE to
expose crypt() from unistd instead of crypt.h on Linux.
  • Loading branch information
kristapsdz committed Aug 10, 2024
1 parent fb6ec89 commit be17364
Show file tree
Hide file tree
Showing 16 changed files with 296 additions and 72 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ REGRESS_NODEP = regress/blowfish \
regress/minor \
regress/mkfifoat \
regress/mknodat \
regress/PASSWORD_LEN \
regress/PATH_MAX \
regress/pledge \
regress/reallocarray \
Expand All @@ -37,6 +38,7 @@ REGRESS_NODEP = regress/blowfish \
regress/sys_queue \
regress/systrace \
regress/termios \
regress/timingsafe_bcmp \
regress/unveil \
regress/WAIT_ANY
REGRESS = $(REGRESS_B64) \
Expand Down
5 changes: 4 additions & 1 deletion Makefile.regen
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ COMPATS = compat_blowfish.c \
compat_strlcpy.c \
compat_strndup.c \
compat_strnlen.c \
compat_strtonum.c
compat_strtonum.c \
compat_timingsafe_bcmp.c
TESTS = test-__progname.c \
test-arc4random.c \
test-blowfish.c \
Expand All @@ -48,6 +49,7 @@ TESTS = test-__progname.c \
test-mkfifoat.c \
test-mknodat.c \
test-osbyteorder_h.c \
test-PASSWORD_LEN.c \
test-PATH_MAX.c \
test-pledge.c \
test-program_invocation_short_name.c \
Expand All @@ -74,6 +76,7 @@ TESTS = test-__progname.c \
test-sys_sysmacros_h.c \
test-sys_tree.c \
test-termios.c \
test-timingsafe_bcmp.c \
test-unveil.c \
test-WAIT_ANY.c

Expand Down
35 changes: 6 additions & 29 deletions compat_crypt_newhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
Expand All @@ -63,7 +64,7 @@ static int decode_base64(u_int8_t *, size_t, const char *);
* Generates a salt for this version of crypt.
*/
static int
bcrypt_initsalt(int log_rounds, uint8_t *salt, size_t saltbuflen)
bcrypt_initsalt(int log_rounds, char *salt, size_t saltbuflen)
{
uint8_t csalt[BCRYPT_MAXSALT];

Expand Down Expand Up @@ -202,7 +203,7 @@ bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
/*
* user friendly functions
*/
int
static int
bcrypt_newhash(const char *pass, int log_rounds, char *hash, size_t hashlen)
{
char salt[BCRYPT_SALTSPACE];
Expand Down Expand Up @@ -298,7 +299,7 @@ static int
decode_base64(u_int8_t *buffer, size_t len, const char *b64data)
{
u_int8_t *bp = buffer;
const u_int8_t *p = b64data;
const u_int8_t *p = (const u_int8_t *)b64data;
u_int8_t c1, c2, c3, c4;

while (bp < buffer + len) {
Expand Down Expand Up @@ -340,7 +341,7 @@ decode_base64(u_int8_t *buffer, size_t len, const char *b64data)
static int
encode_base64(char *b64buffer, const u_int8_t *data, size_t len)
{
u_int8_t *bp = b64buffer;
u_int8_t *bp = (u_int8_t *)b64buffer;
const u_int8_t *p = data;
u_int8_t c1, c2;

Expand Down Expand Up @@ -369,30 +370,6 @@ encode_base64(char *b64buffer, const u_int8_t *data, size_t len)
return 0;
}

/*
* classic interface
*/
static char *
bcrypt_gensalt(u_int8_t log_rounds)
{
static char gsalt[BCRYPT_SALTSPACE];

bcrypt_initsalt(log_rounds, gsalt, sizeof(gsalt));

return gsalt;
}

static char *
bcrypt(const char *pass, const char *salt)
{
static char gencrypted[BCRYPT_HASHSPACE];

if (bcrypt_hashpass(pass, salt, gencrypted, sizeof(gencrypted)) != 0)
return NULL;

return gencrypted;
}

int
crypt_checkpass(const char *pass, const char *goodhash)
{
Expand Down Expand Up @@ -429,7 +406,7 @@ crypt_newhash(const char *pass, const char *pref, char *hash, size_t hashlen)
const char *errstr;
const char *choices[] = { "blowfish", "bcrypt" };
size_t maxchoice = sizeof(choices) / sizeof(choices[0]);
int i;
size_t i;
int rounds;

if (pref == NULL)
Expand Down
74 changes: 74 additions & 0 deletions compat_timingsafe_bcmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@

/* $OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ */
/*
* Copyright (c) 2010 Damien Miller. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

int
timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
const unsigned char *p1 = b1, *p2 = b2;
int ret = 0;

for (; n > 0; n--)
ret |= *p1++ ^ *p2++;
return (ret != 0);
}

/* $OpenBSD: timingsafe_memcmp.c,v 1.2 2015/08/31 02:53:57 guenther Exp $ */
/*
* Copyright (c) 2014 Google Inc.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <limits.h>

int
timingsafe_memcmp(const void *b1, const void *b2, size_t len)
{
const unsigned char *p1 = b1, *p2 = b2;
size_t i;
int res = 0, done = 0;

for (i = 0; i < len; i++) {
/* lt is -1 if p1[i] < p2[i]; else 0. */
int lt = (p1[i] - p2[i]) >> CHAR_BIT;

/* gt is -1 if p1[i] > p2[i]; else 0. */
int gt = (p2[i] - p1[i]) >> CHAR_BIT;

/* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
int cmp = lt - gt;

/* set res = cmp if !done. */
res |= cmp & ~done;

/* set done if p1[i] != p2[i]. */
done |= lt | gt;
}

return (res);
}
111 changes: 82 additions & 29 deletions compats.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,7 @@ blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len)
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
Expand All @@ -694,7 +695,7 @@ static int decode_base64(u_int8_t *, size_t, const char *);
* Generates a salt for this version of crypt.
*/
static int
bcrypt_initsalt(int log_rounds, uint8_t *salt, size_t saltbuflen)
bcrypt_initsalt(int log_rounds, char *salt, size_t saltbuflen)
{
uint8_t csalt[BCRYPT_MAXSALT];

Expand Down Expand Up @@ -833,7 +834,7 @@ bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
/*
* user friendly functions
*/
int
static int
bcrypt_newhash(const char *pass, int log_rounds, char *hash, size_t hashlen)
{
char salt[BCRYPT_SALTSPACE];
Expand Down Expand Up @@ -929,7 +930,7 @@ static int
decode_base64(u_int8_t *buffer, size_t len, const char *b64data)
{
u_int8_t *bp = buffer;
const u_int8_t *p = b64data;
const u_int8_t *p = (const u_int8_t *)b64data;
u_int8_t c1, c2, c3, c4;

while (bp < buffer + len) {
Expand Down Expand Up @@ -971,7 +972,7 @@ decode_base64(u_int8_t *buffer, size_t len, const char *b64data)
static int
encode_base64(char *b64buffer, const u_int8_t *data, size_t len)
{
u_int8_t *bp = b64buffer;
u_int8_t *bp = (u_int8_t *)b64buffer;
const u_int8_t *p = data;
u_int8_t c1, c2;

Expand Down Expand Up @@ -1000,30 +1001,6 @@ encode_base64(char *b64buffer, const u_int8_t *data, size_t len)
return 0;
}

/*
* classic interface
*/
static char *
bcrypt_gensalt(u_int8_t log_rounds)
{
static char gsalt[BCRYPT_SALTSPACE];

bcrypt_initsalt(log_rounds, gsalt, sizeof(gsalt));

return gsalt;
}

static char *
bcrypt(const char *pass, const char *salt)
{
static char gencrypted[BCRYPT_HASHSPACE];

if (bcrypt_hashpass(pass, salt, gencrypted, sizeof(gencrypted)) != 0)
return NULL;

return gencrypted;
}

int
crypt_checkpass(const char *pass, const char *goodhash)
{
Expand Down Expand Up @@ -1060,7 +1037,7 @@ crypt_newhash(const char *pass, const char *pref, char *hash, size_t hashlen)
const char *errstr;
const char *choices[] = { "blowfish", "bcrypt" };
size_t maxchoice = sizeof(choices) / sizeof(choices[0]);
int i;
size_t i;
int rounds;

if (pref == NULL)
Expand Down Expand Up @@ -5280,3 +5257,79 @@ strtonum(const char *numstr, long long minval, long long maxval,
return (ll);
}
#endif /* !HAVE_STRTONUM */
#if !HAVE_TIMINGSAFE_BCMP

/* $OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ */
/*
* Copyright (c) 2010 Damien Miller. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

int
timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
const unsigned char *p1 = b1, *p2 = b2;
int ret = 0;

for (; n > 0; n--)
ret |= *p1++ ^ *p2++;
return (ret != 0);
}

/* $OpenBSD: timingsafe_memcmp.c,v 1.2 2015/08/31 02:53:57 guenther Exp $ */
/*
* Copyright (c) 2014 Google Inc.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <limits.h>

int
timingsafe_memcmp(const void *b1, const void *b2, size_t len)
{
const unsigned char *p1 = b1, *p2 = b2;
size_t i;
int res = 0, done = 0;

for (i = 0; i < len; i++) {
/* lt is -1 if p1[i] < p2[i]; else 0. */
int lt = (p1[i] - p2[i]) >> CHAR_BIT;

/* gt is -1 if p1[i] > p2[i]; else 0. */
int gt = (p2[i] - p1[i]) >> CHAR_BIT;

/* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
int cmp = lt - gt;

/* set res = cmp if !done. */
res |= cmp & ~done;

/* set done if p1[i] != p2[i]. */
done |= lt | gt;
}

return (res);
}
#endif /* !HAVE_TIMINGSAFE_BCMP */
Loading

0 comments on commit be17364

Please sign in to comment.