lobase

Linux port of OpenBSDs userland.
Log | Files | Refs | README

commit 0bf865f90eb58776bf8903caa2ec8897bb1f5e3c
parent d076cb6279b059a46a34d46a4577f2a9f141035c
Author: Duncaen <mail@duncano.de>
Date:   Fri, 16 Jun 2017 00:31:49 +0200

lib/libopenbsd: add crypt(3)

Diffstat:
include/compat.h | 3+++
include/unistd.h | 1+
lib/libopenbsd/crypt/Makefile.inc | 2+-
lib/libopenbsd/crypt/crypt.3 | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/libopenbsd/crypt/crypt.c | 22++++++++++++++++++++++
lib/libopenbsd/crypt/crypt_checkpass.3 | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/libopenbsd/crypt/cryptutil.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/libopenbsd/hidden/pwd.h | 45+++++++++++++++++++++++++++++++++++++++++++++
lib/libopenbsd/include/namespace.h | 2+-
9 files changed, 423 insertions(+), 2 deletions(-)

diff --git a/include/compat.h b/include/compat.h @@ -18,6 +18,9 @@ #define __BEGIN_DECLS #define __END_DECLS +#define __BEGIN_HIDDEN_DECLS +#define __END_HIDDEN_DECLS + #ifndef __CONCAT #define __CONCAT(x,y) x ## y #endif diff --git a/include/unistd.h b/include/unistd.h @@ -44,6 +44,7 @@ int execvpe(const char *, char *const *, char *const *); int closefrom(int); +int crypt_newhash(const char *, const char *, char *, size_t); int getdtablecount(void); int getentropy(void *, size_t); mode_t getmode(const void *, mode_t); diff --git a/lib/libopenbsd/crypt/Makefile.inc b/lib/libopenbsd/crypt/Makefile.inc @@ -2,6 +2,6 @@ VPATH+= ${LIBCSRCDIR}/arch/${MACHINE_CPU}/crypt ${LIBCSRCDIR}/crypt -SRCS+= arc4random.c arc4random_uniform.c bcrypt.c blowfish.c +SRCS+= arc4random.c arc4random_uniform.c bcrypt.c blowfish.c crypt.c cryptutil.c MAN+= blowfish.3 arc4random.3 diff --git a/lib/libopenbsd/crypt/crypt.3 b/lib/libopenbsd/crypt/crypt.3 @@ -0,0 +1,144 @@ +.\" $OpenBSD: crypt.3,v 1.45 2015/04/06 20:49:41 tedu Exp $ +.\" +.\" FreeSec: libcrypt +.\" +.\" Copyright (c) 1994 David Burren +.\" 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. +.\" 4. Neither the name of the author nor the names of other contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. +.\" +.\" Manual page, using -mandoc macros +.\" +.Dd $Mdocdate: April 6 2015 $ +.Dt CRYPT 3 +.Os +.Sh NAME +.Nm crypt , +.Nm bcrypt_gensalt , +.Nm bcrypt +.Nd password hashing +.Sh SYNOPSIS +.In stdlib.h +.Pp +.In unistd.h +.Ft char * +.Fn crypt "const char *key" "const char *setting" +.In pwd.h +.Ft char * +.Fn bcrypt_gensalt "u_int8_t log_rounds" +.Ft char * +.Fn bcrypt "const char *key" "const char *salt" +.Sh DESCRIPTION +These functions are deprecated in favor of +.Xr crypt_checkpass 3 +and +.Xr crypt_newhash 3 . +.Pp +The +.Fn crypt +function performs password hashing. +Additional code has been added to deter key search attempts and to use +stronger hashing algorithms. +.Pp +The first argument to +.Fn crypt +is a NUL-terminated +string +.Fa key , +typically a user's typed password. +The second, +.Fa setting , +currently supports a single form. +If it begins +with a string character +.Pq Ql $ +and a number then a different algorithm is used depending on the number. +At the moment +.Ql $2 +chooses Blowfish hashing; see below for more information. +.Ss Blowfish crypt +The Blowfish version of crypt has 128 bits of +.Fa salt +in order to make building dictionaries of common passwords space consuming. +The initial state of the +Blowfish cipher is expanded using the +.Fa salt +and the +.Fa password +repeating the process a variable number of rounds, which is encoded in +the password string. +The maximum password length is 72. +The final Blowfish password entry is created by encrypting the string +.Pp +.Dq OrpheanBeholderScryDoubt +.Pp +with the Blowfish state 64 times. +.Pp +The version number, the logarithm of the number of rounds and +the concatenation of salt and hashed password are separated by the +.Ql $ +character. +An encoded +.Sq 8 +would specify 256 rounds. +A valid Blowfish password looks like this: +.Pp +.Dq $2b$12$FPWWO2RJ3CK4FINTw0Hi8OiPKJcX653gzSS.jqltHFMxyDmmQ0Hqq . +.Pp +The whole Blowfish password string is passed as +.Fa setting +for interpretation. +.Sh RETURN VALUES +The function +.Fn crypt +returns a pointer to the encrypted value on success, and +.Dv NULL +on failure. +.Sh SEE ALSO +.Xr encrypt 1 , +.Xr login 1 , +.Xr passwd 1 , +.Xr blowfish 3 , +.Xr crypt_checkpass 3 , +.Xr getpass 3 , +.Xr passwd 5 +.Sh HISTORY +A rotor-based +.Fn crypt +function appeared in +.At v3 . +A DES-based +.Fn crypt +first appeared in +.At v7 . +.Fn bcrypt +first appeared in +.Ox 2.1 . +.Sh BUGS +The +.Fn crypt +function returns a pointer to static data, and subsequent calls to +.Fn crypt +will modify the same object. diff --git a/lib/libopenbsd/crypt/crypt.c b/lib/libopenbsd/crypt/crypt.c @@ -0,0 +1,22 @@ +/* $OpenBSD: crypt.c,v 1.31 2015/09/12 14:56:50 guenther Exp $ */ + +#include <errno.h> +#include <pwd.h> +#include <unistd.h> + +char * +crypt(const char *key, const char *setting) +{ + if (setting[0] == '$') { + switch (setting[1]) { + case '2': + return bcrypt(key, setting); + default: + errno = EINVAL; + return (NULL); + } + } + errno = EINVAL; + return (NULL); +} +DEF_WEAK(crypt); diff --git a/lib/libopenbsd/crypt/crypt_checkpass.3 b/lib/libopenbsd/crypt/crypt_checkpass.3 @@ -0,0 +1,107 @@ +.\" $OpenBSD: crypt_checkpass.3,v 1.9 2015/07/23 22:20:02 tedu Exp $ +.\" +.\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> +.\" +.\" 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. +.\" +.Dd $Mdocdate: July 23 2015 $ +.Dt CRYPT_CHECKPASS 3 +.Os +.Sh NAME +.Nm crypt_checkpass , +.Nm crypt_newhash +.Nd password hashing +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn crypt_checkpass "const char *password" "const char *hash" +.Ft int +.Fn crypt_newhash "const char *password" "const char *pref" "char *hash" "size_t hashsize" +.Sh DESCRIPTION +The +.Fn crypt_checkpass +function is provided to simplify checking a user's password. +If both the +.Fa hash +and the +.Fa password +are the empty string, authentication +is a success. +Otherwise, the +.Fa password +is hashed and compared to the provided +.Fa hash . +If the +.Fa hash +is +.Dv NULL , +authentication will always fail, but a default +amount of work is performed to simulate the hashing operation. +A successful match will return 0. +A failure will return \-1 and set +.Xr errno 2 . +.Pp +The +.Fn crypt_newhash +function is provided to simplify the creation of new password hashes. +The provided +.Fa password +is randomly salted and hashed and stored in +.Fa hash . +The +.Fa pref +argument identifies the preferred hashing algorithm and parameters. +Possible values are: +.Bl -tag -width Ds +.It Dq bcrypt,<rounds> +The bcrypt algorithm, where the value of rounds can be between 4 and 31 and +specifies the base 2 logarithm of the number of rounds. +The special rounds value +.Sq a +automatically selects rounds based on system performance. +.El +.Sh RETURN VALUES +.Rv -std crypt_checkpass crypt_newhash +.Sh ERRORS +The +.Fn crypt_checkpass +function sets +.Va errno +to +.Er EACCESS +when authentication fails. +.Pp +The +.Fn crypt_newhash +function sets +.Va errno +to +.Er EINVAL +if +.Fa pref +is unsupported. +.Sh SEE ALSO +.Xr crypt 3 , +.Xr login.conf 5 , +.Xr passwd 5 +.Sh HISTORY +The function +.Fn crypt_checkpass +first appeared in +.Ox 5.6 , +and +.Fn crypt_newhash +in +.Ox 5.7 . +.Sh AUTHORS +.An Ted Unangst Aq Mt tedu@openbsd.org diff --git a/lib/libopenbsd/crypt/cryptutil.c b/lib/libopenbsd/crypt/cryptutil.c @@ -0,0 +1,99 @@ +/* $OpenBSD: cryptutil.c,v 1.12 2015/09/13 15:33:48 guenther Exp $ */ +/* + * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> + * + * 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 <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <pwd.h> +#ifdef HAVE_LOGIN_CAP_H +#include <login_cap.h> +#endif +#include <errno.h> + +int +crypt_checkpass(const char *pass, const char *goodhash) +{ + char dummy[_PASSWORD_LEN]; + + if (goodhash == NULL) { + /* fake it */ + goto fake; + } + + /* empty password */ + if (strlen(goodhash) == 0 && strlen(pass) == 0) + return 0; + + if (goodhash[0] == '$' && goodhash[1] == '2') { + if (bcrypt_checkpass(pass, goodhash)) + goto fail; + return 0; + } + + /* unsupported. fake it. */ +fake: + bcrypt_newhash(pass, 8, dummy, sizeof(dummy)); +fail: + errno = EACCES; + return -1; +} +DEF_WEAK(crypt_checkpass); + +int +crypt_newhash(const char *pass, const char *pref, char *hash, size_t hashlen) +{ + int rv = -1; + const char *defaultpref = "blowfish,8"; + const char *errstr; + const char *choices[] = { "blowfish", "bcrypt" }; + size_t maxchoice = sizeof(choices) / sizeof(choices[0]); + int i; + int rounds; + + if (pref == NULL) + pref = defaultpref; + + for (i = 0; i < maxchoice; i++) { + const char *choice = choices[i]; + size_t len = strlen(choice); + if (strcmp(pref, choice) == 0) { + rounds = _bcrypt_autorounds(); + break; + } else if (strncmp(pref, choice, len) == 0 && + pref[len] == ',') { + if (strcmp(pref + len + 1, "a") == 0) { + rounds = _bcrypt_autorounds(); + } else { + rounds = strtonum(pref + len + 1, 4, 31, &errstr); + if (errstr) { + errno = EINVAL; + goto err; + } + } + break; + } + } + if (i == maxchoice) { + errno = EINVAL; + goto err; + } + + rv = bcrypt_newhash(pass, rounds, hash, hashlen); + +err: + return rv; +} +DEF_WEAK(crypt_newhash); diff --git a/lib/libopenbsd/hidden/pwd.h b/lib/libopenbsd/hidden/pwd.h @@ -0,0 +1,45 @@ +/* $OpenBSD: pwd.h,v 1.3 2015/11/24 22:03:33 millert Exp $ */ +/* + * Copyright (c) 2015 Philip Guenther <guenther@openbsd.org> + * + * 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. + */ + +#ifndef _LIBC_PWD_H_ +#define _LIBC_PWD_H_ + +#include_next <pwd.h> + +__BEGIN_HIDDEN_DECLS +int _bcrypt_autorounds(void); +__END_HIDDEN_DECLS + + +PROTO_NORMAL(bcrypt); +PROTO_NORMAL(bcrypt_checkpass); +PROTO_DEPRECATED(bcrypt_gensalt); +PROTO_NORMAL(bcrypt_newhash); +PROTO_DEPRECATED(endpwent); +PROTO_DEPRECATED(getpwent); +PROTO_DEPRECATED(getpwnam); +PROTO_NORMAL(getpwnam_r); +PROTO_NORMAL(getpwnam_shadow); +PROTO_DEPRECATED(getpwuid); +PROTO_NORMAL(getpwuid_r); +PROTO_NORMAL(getpwuid_shadow); +PROTO_NORMAL(pw_dup); +PROTO_NORMAL(setpassent); +PROTO_DEPRECATED(setpwent); +PROTO_DEPRECATED(user_from_uid); + +#endif /* !_LIBC_PWD_H_ */ diff --git a/lib/libopenbsd/include/namespace.h b/lib/libopenbsd/include/namespace.h @@ -145,7 +145,7 @@ /* #define PROTO_NORMAL(x) __dso_hidden typeof(x) x asm(HIDDEN_STRING(x)) */ /* #define PROTO_STD_DEPRECATED(x) typeof(x) x __attribute__((deprecated)) */ -/* #define PROTO_DEPRECATED(x) typeof(x) x __attribute__((deprecated, weak)) */ +#define PROTO_DEPRECATED(x) typeof(x) x __attribute__((deprecated, weak)) /* #define PROTO_CANCEL(x) __dso_hidden typeof(x) HIDDEN(x), \ */ /* x asm(CANCEL_STRING(x)) */ /* #define PROTO_WRAP(x) PROTO_NORMAL(x), WRAP(x) */