# $NetBSD: Makefile,v 1.24 2012/08/10 04:30:47 joerg Exp $
USE_SHLIBDIR= yes
-#LSC MINIX Until the library gets updated
-NOGCCERROR=yes
LIB= crypt
-/* $NetBSD: bcrypt.c,v 1.9 2006/10/27 19:39:11 drochner Exp $ */
+/* $NetBSD: bcrypt.c,v 1.17 2012/08/30 12:16:49 drochner Exp $ */
/* $OpenBSD: bcrypt.c,v 1.16 2002/02/19 19:39:36 millert Exp $ */
/*
*
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: bcrypt.c,v 1.9 2006/10/27 19:39:11 drochner Exp $");
+__RCSID("$NetBSD: bcrypt.c,v 1.17 2012/08/30 12:16:49 drochner Exp $");
#include <stdio.h>
#include <stdlib.h>
#define BCRYPT_VERSION '2'
#define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */
-#define BCRYPT_MAXSALTLEN (BCRYPT_MAXSALT * 4 / 3 + 1)
+#define BCRYPT_MAXSALTLEN (7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1)
#define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
#define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */
char *__bcrypt(const char *, const char *); /* XXX */
static char encrypted[_PASSWORD_LEN];
-static char error[] = ":";
static const u_int8_t Base64Code[] =
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
if (errno == ERANGE && nrounds == ULONG_MAX)
return -1;
- if (nrounds > 255) {
- errno = EINVAL;
- return -1;
- }
-
if (nrounds < 4)
nrounds = 4;
+ else if (nrounds > 31)
+ nrounds = 31;
for (i = 0; i < BCRYPT_MAXSALT; i++) {
if (i % 4 == 0)
i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
char *
-__bcrypt(key, salt)
- const char *key;
- const char *salt;
+__bcrypt(const char *key, const char *salt)
{
blf_ctx state;
u_int32_t rounds, i, k;
u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
u_int8_t csalt[BCRYPT_MAXSALT];
u_int32_t cdata[BCRYPT_BLOCKS];
+ int n;
+ size_t len;
/* Discard "$" identifier */
salt++;
- if (*salt > BCRYPT_VERSION) {
- /* How do I handle errors ? Return ':' */
- return error;
- }
+ if (*salt > BCRYPT_VERSION)
+ return NULL;
/* Check for minor versions */
if (salt[1] != '$') {
- switch (salt[1]) {
- case 'a':
- /* 'ab' should not yield the same as 'abab' */
- minor = salt[1];
- salt++;
- break;
- default:
- return error;
- }
+ switch (salt[1]) {
+ case 'a':
+ /* 'ab' should not yield the same as 'abab' */
+ minor = salt[1];
+ salt++;
+ break;
+ default:
+ return NULL;
+ }
} else
minor = 0;
if (salt[2] != '$')
/* Out of sync with passwd entry */
- return error;
+ return NULL;
/* Computer power doesn't increase linear, 2^x should be fine */
- if ((rounds = (u_int32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS)
- return error;
+ n = atoi(salt);
+ if (n > 31 || n < 0)
+ return NULL;
+ logr = (u_int8_t)n;
+ if ((rounds = (u_int32_t) 1 << logr) < BCRYPT_MINROUNDS)
+ return NULL;
/* Discard num rounds + "$" identifier */
salt += 3;
if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
- return error;
+ return NULL;
/* We dont want the base64 salt but the raw data */
decode_base64(csalt, BCRYPT_MAXSALT, (const u_int8_t *)salt);
salt_len = BCRYPT_MAXSALT;
- key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
+ len = strlen(key);
+ if (len > 72)
+ key_len = 72;
+ else
+ key_len = (uint8_t)len;
+ key_len += minor >= 'a' ? 1 : 0;
/* Setting up S-Boxes and Subkeys */
Blowfish_initstate(&state);
encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
4 * BCRYPT_BLOCKS - 1);
+ __explicit_bzero(&state, sizeof(state));
return encrypted;
}
-/* $NetBSD: crypt-sha1.c,v 1.3 2006/10/27 18:22:56 drochner Exp $ */
+/* $NetBSD: crypt-sha1.c,v 1.5 2012/08/30 12:16:49 drochner Exp $ */
/*
* Copyright (c) 2004, Juniper Networks, Inc.
#include <sys/cdefs.h>
#if !defined(lint)
-__RCSID("$NetBSD: crypt-sha1.c,v 1.3 2006/10/27 18:22:56 drochner Exp $");
+__RCSID("$NetBSD: crypt-sha1.c,v 1.5 2012/08/30 12:16:49 drochner Exp $");
#endif /* not lint */
#include <stdlib.h>
static unsigned char hmac_buf[SHA1_SIZE];
static char passwd[(2 * sizeof(SHA1_MAGIC)) +
CRYPT_SHA1_SALT_LENGTH + SHA1_SIZE];
- char *sp;
+ const char *sp;
char *ep;
unsigned long ul;
int sl;
* $<tag>$<iterations>$salt[$]
* If it does not start with $ we use our default iterations.
*/
- sp = __UNCONST(salt);
/* If it starts with the magic string, then skip that */
- if (!strncmp(sp, magic, strlen(magic))) {
- sp += strlen(magic);
+ if (!strncmp(salt, magic, strlen(magic))) {
+ salt += strlen(magic);
/* and get the iteration count */
- iterations = strtoul(sp, &ep, 10);
+ iterations = strtoul(salt, &ep, 10);
if (*ep != '$')
return NULL; /* invalid input */
- sp = ep + 1; /* skip over the '$' */
+ salt = ep + 1; /* skip over the '$' */
} else {
iterations = __crypt_sha1_iterations(0);
}
/* It stops at the next '$', max CRYPT_SHA1_ITERATIONS chars */
- for (ep = sp; *ep && *ep != '$' && ep < (sp + CRYPT_SHA1_ITERATIONS); ep++)
+ for (sp = salt; *sp && *sp != '$' && sp < (salt + CRYPT_SHA1_ITERATIONS); sp++)
continue;
/* Get the length of the actual salt */
- sl = ep - sp;
+ sl = sp - salt;
pl = strlen(pw);
/*
* Prime the pump with <salt><magic><iterations>
*/
dl = snprintf(passwd, sizeof (passwd), "%.*s%s%u",
- sl, sp, magic, iterations);
+ sl, salt, magic, iterations);
/*
* Then hmac using <pw> as key, and repeat...
*/
- ep = __UNCONST(pw); /* keep gcc happy */
- __hmac_sha1(passwd, dl, ep, pl, hmac_buf);
+ __hmac_sha1(passwd, dl, pw, pl, hmac_buf);
for (i = 1; i < iterations; i++) {
- __hmac_sha1(hmac_buf, SHA1_SIZE, ep, pl, hmac_buf);
+ __hmac_sha1(hmac_buf, SHA1_SIZE, pw, pl, hmac_buf);
}
/* Now output... */
pl = snprintf(passwd, sizeof(passwd), "%s%u$%.*s$",
- magic, iterations, sl, sp);
+ magic, iterations, sl, salt);
ep = passwd + pl;
/* Every 3 bytes of hash gives 24 bits which is 4 base64 chars */
*ep = '\0';
/* Don't leave anything around in vm they could use. */
- memset(hmac_buf, 0, sizeof hmac_buf);
+ __explicit_bzero(hmac_buf, sizeof hmac_buf);
return passwd;
}
-.\" $NetBSD: crypt.3,v 1.20 2005/09/05 03:37:15 hubertf Exp $
+.\" $NetBSD: crypt.3,v 1.27 2012/03/23 18:08:35 njoly Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" @(#)crypt.3 8.2 (Berkeley) 12/11/93
.\"
-.Dd September 4, 2005
+.Dd January 1, 2012
.Dt CRYPT 3
.Os
.Sh NAME
.Lb libcrypt
.Sh SYNOPSIS
.In unistd.h
-.Ft char
-.Fn *crypt "const char *key" "const char *setting"
+.Ft "char *"
+.Fn crypt "const char *key" "const char *setting"
.Ft int
.Fn encrypt "char *block" "int flag"
.Ft int
followed by the encoded 64-bit encryption.
.Pp
For compatibility with historical versions of
-.Xr crypt 3 ,
+.Fn crypt ,
the
.Ar setting
may consist of 2 bytes of salt, encoded as above, in which case an
.Ss "Blowfish" crypt
The
.Tn Blowfish
-version of crypt has 128 bits of
+version of
+.Fn crypt
+has 128 bits of
.Fa salt
in order to make building dictionaries of common passwords space consuming.
The initial state of the
.Sh RETURN VALUES
The function
.Fn crypt
-returns a pointer to the encrypted value on success and NULL on failure.
+returns a pointer to the encrypted value on success.
+.Pp
+The behavior of
+.Fn crypt
+on errors isn't well standardized.
+Some implementations simply can't fail (unless the process dies, in which
+case they obviously can't return), others return
+.Dv NULL
+or a fixed string.
+Most implementations don't set
+.Va errno ,
+but some do.
+.St -susv2
+specifies
+only returning
+.Dv NULL
+and setting
+.Va errno
+as a valid behavior, and defines
+only one possible error
+.Er ( ENOSYS ,
+.Dq "The functionality is not supported on this implementation." )
+Unfortunately, most existing applications aren't prepared to handle
+.Dv NULL
+returns from
+.Fn crypt .
+The description below corresponds to this implementation of
+.Fn crypt
+only.
+The behavior may change to match standards, other implementations or existing
+applications.
+.Pp
+.Fn crypt
+may only fail (and return) when passed an invalid or unsupported
+.Fa setting ,
+in which case it returns a pointer to a magic string that is shorter than 13
+characters and is guaranteed to differ from
+.Fa setting .
+This behavior is safe for older applications which assume that
+.Fn crypt
+can't fail, when both setting new passwords and authenticating against
+existing password hashes.
+.Pp
The functions
.Fn setkey ,
.Fn encrypt ,
Subsequent calls to
.Fn crypt
will modify the same object.
+.Pp
+Before
+.Nx 6.0
+.Fn crypt
+returned either
+.Dv NULL
+or
+.Dv \&:
+on error.
-/* $NetBSD: crypt.c,v 1.28 2009/05/01 00:28:17 perry Exp $ */
+/* $NetBSD: crypt.c,v 1.33 2011/12/28 03:13:09 christos Exp $ */
/*
* Copyright (c) 1989, 1993
#if 0
static char sccsid[] = "@(#)crypt.c 8.1.1.1 (Berkeley) 8/18/93";
#else
-__RCSID("$NetBSD: crypt.c,v 1.28 2009/05/01 00:28:17 perry Exp $");
+__RCSID("$NetBSD: crypt.c,v 1.33 2011/12/28 03:13:09 christos Exp $");
#endif
#endif /* not lint */
/* ===== Tables that are initialized at run time ==================== */
-static unsigned char a64toi[128]; /* ascii-64 => 0..63 */
-
/* Initial key schedule permutation */
static C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
static C_block constdatablock; /* encryption constant */
static char cryptresult[1+4+4+11+1]; /* encrypted result */
+/*
+ * We match the behavior of UFC-crypt on systems where "char" is signed by
+ * default (the majority), regardless of char's signedness on our system.
+ */
+static inline int
+ascii_to_bin(char ch)
+{
+ signed char sch = ch;
+ int retval;
+
+ if (sch >= 'a')
+ retval = sch - ('a' - 38);
+ else if (sch >= 'A')
+ retval = sch - ('A' - 12);
+ else
+ retval = sch - '.';
+
+ return retval & 0x3f;
+}
+
+/*
+ * When we choose to "support" invalid salts, nevertheless disallow those
+ * containing characters that would violate the passwd file format.
+ */
+static inline int
+ascii_is_unsafe(char ch)
+{
+ return !ch || ch == '\n' || ch == ':';
+}
/*
* Return a pointer to static data consisting of the "setting"
* followed by an encryption produced by the "key" and "setting".
*/
-char *
-crypt(const char *key, const char *setting)
+static char *
+__crypt(const char *key, const char *setting)
{
char *encp;
int32_t i;
key++;
keyblock.b[i] = t;
}
- if (des_setkey((char *)keyblock.b)) /* also initializes "a64toi" */
+ if (des_setkey((char *)keyblock.b))
return (NULL);
encp = &cryptresult[0];
/* get iteration count */
num_iter = 0;
for (i = 4; --i >= 0; ) {
- if ((t = (unsigned char)setting[i]) == '\0')
- t = '.';
- encp[i] = t;
- num_iter = (num_iter<<6) | a64toi[t];
+ int value = ascii_to_bin(setting[i]);
+ if (itoa64[value] != setting[i])
+ return NULL;
+ encp[i] = setting[i];
+ num_iter = (num_iter << 6) | value;
}
+ if (num_iter == 0)
+ return NULL;
setting += 4;
encp += 4;
salt_size = 4;
default:
num_iter = 25;
salt_size = 2;
+ if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1]))
+ return NULL;
}
salt = 0;
for (i = salt_size; --i >= 0; ) {
- if ((t = (unsigned char)setting[i]) == '\0')
- t = '.';
- encp[i] = t;
- salt = (salt<<6) | a64toi[t];
+ int value = ascii_to_bin(setting[i]);
+ if (salt_size > 2 && itoa64[value] != setting[i])
+ return NULL;
+ encp[i] = setting[i];
+ salt = (salt << 6) | value;
}
encp += salt_size;
if (des_cipher((char *)(void *)&constdatablock,
return (cryptresult);
}
+char *
+crypt(const char *key, const char *salt)
+{
+ char *res = __crypt(key, salt);
+ if (res)
+ return res;
+ /* How do I handle errors ? Return "*0" or "*1" */
+ return __UNCONST(salt[0] == '*' && salt[1] == '0' ? "*1" : "*0");
+}
/*
* The Key Schedule, filled in by des_setkey() or setkey().
int tableno;
static unsigned char perm[64], tmp32[32]; /* "static" for speed */
- /*
- * table that converts chars "./0-9A-Za-z"to integers 0-63.
- */
- for (i = 0; i < 64; i++)
- a64toi[itoa64[i]] = i;
-
/*
* PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
*/
-/* $NetBSD: hmac.c,v 1.2 2009/01/18 12:15:27 lukem Exp $ */
+/* $NetBSD: hmac.c,v 1.3 2011/05/16 10:39:12 drochner Exp $ */
/*
* Copyright (c) 2004, Juniper Networks, Inc.
*/
#include <sys/cdefs.h>
#if !defined(lint)
-__RCSID("$NetBSD: hmac.c,v 1.2 2009/01/18 12:15:27 lukem Exp $");
+__RCSID("$NetBSD: hmac.c,v 1.3 2011/05/16 10:39:12 drochner Exp $");
#endif /* not lint */
#include <stdlib.h>
{
HASH_CTX context;
/* Inner padding key XOR'd with ipad */
- unsigned char k_ipad[HMAC_BLOCKSZ + 1];
+ unsigned char k_ipad[HMAC_BLOCKSZ];
/* Outer padding key XOR'd with opad */
- unsigned char k_opad[HMAC_BLOCKSZ + 1];
+ unsigned char k_opad[HMAC_BLOCKSZ];
/* HASH(key) if needed */
unsigned char tk[HASH_LENGTH];
size_t i;
-/* $NetBSD: md5crypt.c,v 1.9 2007/01/17 23:24:22 hubertf Exp $ */
+/* $NetBSD: md5crypt.c,v 1.12 2012/08/30 12:16:49 drochner Exp $ */
/*
* ----------------------------------------------------------------------------
#include <sys/cdefs.h>
#if !defined(lint)
-__RCSID("$NetBSD: md5crypt.c,v 1.9 2007/01/17 23:24:22 hubertf Exp $");
+__RCSID("$NetBSD: md5crypt.c,v 1.12 2012/08/30 12:16:49 drochner Exp $");
#endif /* not lint */
-/*
- * NOTE: We are also built for inclusion in libcrypto; when built for that
- * environment, use the libcrypto versions of the MD5 routines, so save
- * having to pull two versions into the same program.
- */
-
#include <unistd.h>
#include <stdio.h>
#include <string.h>
-#ifdef libcrypto
-#include <openssl/md5.h>
-#else
#include <md5.h>
-#endif
#include "crypt.h"
#define MD5_MAGIC "$1$"
#define MD5_MAGIC_LEN 3
-#ifdef libcrypto
-#define INIT(x) MD5_Init((x))
-#define UPDATE(x, b, l) MD5_Update((x), (b), (l))
-#define FINAL(v, x) MD5_Final((v), (x))
-#else
#define INIT(x) MD5Init((x))
#define UPDATE(x, b, l) MD5Update((x), (b), (l))
#define FINAL(v, x) MD5Final((v), (x))
-#endif
/*
FINAL(final, &ctx);
+ /* memset(&ctx, 0, sizeof(ctx)); done by MD5Final() */
+
/*
* And now, just to make sure things don't run too fast. On a 60 MHz
* Pentium this takes 34 msec, so you would need 30 seconds to build
FINAL(final, &ctx1);
}
+ /* memset(&ctx1, 0, sizeof(ctx1)); done by MD5Final() */
+
p = passwd + sl + MD5_MAGIC_LEN + 1;
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; __crypt_to64(p,l,4); p += 4;
*p = '\0';
/* Don't leave anything around in vm they could use. */
- memset(final, 0, sizeof(final));
+ __explicit_bzero(final, sizeof(final));
return (passwd);
}
+# $NetBSD: shlib_version,v 1.6 2009/01/11 03:07:47 christos Exp $
+# Remember to update distrib/sets/lists/base/shl.* when changing
+#
major=0
minor=0
2012/10/17 12:00:00,lib/csu
2012/10/17 12:00:00,lib/libbz2
2012/10/17 12:00:00,lib/libc
-2009/05/01 00:28:17,lib/libcrypt
+2012/10/17 12:00:00,lib/libcrypt
2012/10/17 12:00:00,lib/libcurses
2012/10/17 12:00:00,lib/libm
2011/09/30 22:08:19,lib/libprop