Updating lib/libcrypt

Change-Id: I4dc5ca7c86abc5295ffc57386a14dd1d790fd489
This commit is contained in:
Lionel Sambuc 2012-12-18 11:01:53 +01:00
parent e8235bc09a
commit f5435c74b7
9 changed files with 180 additions and 100 deletions

View file

@ -1,8 +1,6 @@
# $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

View file

@ -1,4 +1,4 @@
/* $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 $ */
/*
@ -46,7 +46,7 @@
*
*/
#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>
@ -66,7 +66,7 @@ __RCSID("$NetBSD: bcrypt.c,v 1.9 2006/10/27 19:39:11 drochner Exp $");
#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 */
@ -77,7 +77,6 @@ static void decode_base64(u_int8_t *, u_int16_t, const u_int8_t *);
char *__bcrypt(const char *, const char *); /* XXX */
static char encrypted[_PASSWORD_LEN];
static char error[] = ":";
static const u_int8_t Base64Code[] =
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
@ -175,13 +174,10 @@ __gensalt_blowfish(char *salt, size_t saltlen, const char *option)
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)
@ -214,9 +210,7 @@ bcrypt_gensalt(u_int8_t log_rounds)
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;
@ -225,26 +219,26 @@ __bcrypt(key, salt)
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;
@ -253,22 +247,31 @@ __bcrypt(key, salt)
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);
@ -311,6 +314,7 @@ __bcrypt(key, salt)
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;
}

View file

@ -1,4 +1,4 @@
/* $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.
@ -31,7 +31,7 @@
#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>
@ -122,7 +122,7 @@ __crypt_sha1 (const char *pw, const char *salt)
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;
@ -136,26 +136,25 @@ __crypt_sha1 (const char *pw, const char *salt)
* $<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);
/*
@ -163,18 +162,17 @@ __crypt_sha1 (const char *pw, const char *salt)
* 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 */
@ -192,7 +190,7 @@ __crypt_sha1 (const char *pw, const char *salt)
*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;
}

View file

@ -1,4 +1,4 @@
.\" $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.
@ -29,7 +29,7 @@
.\"
.\" @(#)crypt.3 8.2 (Berkeley) 12/11/93
.\"
.Dd September 4, 2005
.Dd January 1, 2012
.Dt CRYPT 3
.Os
.Sh NAME
@ -43,8 +43,8 @@
.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
@ -137,7 +137,7 @@ of the
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
@ -244,7 +244,9 @@ for interpretation.
.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
@ -281,7 +283,49 @@ for interpretation.
.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 ,
@ -352,3 +396,12 @@ a pointer to that object.
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.

View file

@ -1,4 +1,4 @@
/* $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
@ -37,7 +37,7 @@
#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 */
@ -445,8 +445,6 @@ static const unsigned char itoa64[] = /* 0..63 => ascii-64 */
/* ===== 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];
@ -469,13 +467,42 @@ static C_block CF6464[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;
@ -502,7 +529,7 @@ crypt(const char *key, const char *setting)
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];
@ -529,11 +556,14 @@ crypt(const char *key, const char *setting)
/* 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;
@ -541,14 +571,17 @@ crypt(const char *key, const char *setting)
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,
@ -580,6 +613,15 @@ crypt(const char *key, const char *setting)
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().
@ -750,12 +792,6 @@ init_des(void)
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.
*/

View file

@ -1,4 +1,4 @@
/* $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.
@ -42,7 +42,7 @@
*/
#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>
@ -70,9 +70,9 @@ HMAC_FUNC (const unsigned char *text, size_t text_len,
{
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;

View file

@ -1,4 +1,4 @@
/* $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 $ */
/*
* ----------------------------------------------------------------------------
@ -15,38 +15,22 @@
#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
/*
@ -117,6 +101,8 @@ __md5crypt(const char *pw, const char *salt)
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
@ -144,6 +130,8 @@ __md5crypt(const char *pw, const char *salt)
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;
@ -155,6 +143,6 @@ __md5crypt(const char *pw, const char *salt)
*p = '\0';
/* Don't leave anything around in vm they could use. */
memset(final, 0, sizeof(final));
__explicit_bzero(final, sizeof(final));
return (passwd);
}

View file

@ -1,2 +1,5 @@
# $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

View file

@ -55,7 +55,7 @@
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