crypt.c revision 272830
1226048Sobrien/*-
2226048Sobrien * Copyright (c) 1999 Mark Murray
3330569Sgordon * Copyright (c) 2014 Dag-Erling Sm��rgrav
4226048Sobrien * All rights reserved.
5226048Sobrien *
6226048Sobrien * Redistribution and use in source and binary forms, with or without
7226048Sobrien * modification, are permitted provided that the following conditions
8226048Sobrien * are met:
9226048Sobrien * 1. Redistributions of source code must retain the above copyright
10226048Sobrien *    notice, this list of conditions and the following disclaimer.
11226048Sobrien * 2. Redistributions in binary form must reproduce the above copyright
12226048Sobrien *    notice, this list of conditions and the following disclaimer in the
13226048Sobrien *    documentation and/or other materials provided with the distribution.
14226048Sobrien *
15226048Sobrien * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND
16226048Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17226048Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18226048Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL MARK MURRAY OR CONTRIBUTORS BE LIABLE
19226048Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20226048Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21226048Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22226048Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23226048Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24226048Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25226048Sobrien * SUCH DAMAGE.
26226048Sobrien */
27226048Sobrien
28226048Sobrien#include <sys/cdefs.h>
29226048Sobrien__FBSDID("$FreeBSD: head/lib/libcrypt/crypt.c 272830 2014-10-09 16:45:11Z des $");
30226048Sobrien
31226048Sobrien#include <sys/types.h>
32226048Sobrien
33226048Sobrien#include <libutil.h>
34226048Sobrien#include <string.h>
35226048Sobrien#include <unistd.h>
36226048Sobrien
37226048Sobrien#include "crypt.h"
38226048Sobrien
39226048Sobrien/*
40226048Sobrien * List of supported crypt(3) formats.
41226048Sobrien *
42226048Sobrien * The default algorithm is the last entry in the list (second-to-last
43226048Sobrien * array element since the last is a sentinel).  The reason for placing
44226048Sobrien * the default last rather than first is that DES needs to be at the
45226048Sobrien * bottom for the algorithm guessing logic in crypt(3) to work correctly,
46226048Sobrien * and it needs to be the default for backward compatibility.
47226048Sobrien */
48226048Sobrienstatic const struct crypt_format {
49226048Sobrien	const char *const name;
50226048Sobrien	char *(*const func)(const char *, const char *);
51226048Sobrien	const char *const magic;
52226048Sobrien} crypt_formats[] = {
53226048Sobrien	{ "md5",	crypt_md5,		"$1$"	},
54226048Sobrien#ifdef HAS_BLOWFISH
55226048Sobrien	{ "blf",	crypt_blowfish,		"$2"	},
56226048Sobrien#endif
57226048Sobrien	{ "nth",	crypt_nthash,		"$3$"	},
58226048Sobrien	{ "sha256",	crypt_sha256,		"$5$"	},
59226048Sobrien	{ "sha512",	crypt_sha512,		"$6$"	},
60330569Sgordon#ifdef HAS_DES
61226048Sobrien	{ "des",	crypt_des,		"_"	},
62226048Sobrien#endif
63226048Sobrien
64226048Sobrien	/* sentinel */
65226048Sobrien	{ NULL,		NULL,			NULL	}
66226048Sobrien};
67226048Sobrien
68226048Sobrienstatic const struct crypt_format *crypt_format =
69226048Sobrien    &crypt_formats[(sizeof crypt_formats / sizeof *crypt_formats) - 2];
70226048Sobrien
71226048Sobrien#define DES_SALT_ALPHABET \
72226048Sobrien	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
73226048Sobrien
74226048Sobrien/*
75226048Sobrien * Returns the name of the currently selected format.
76226048Sobrien */
77226048Sobrienconst char *
78226048Sobriencrypt_get_format(void)
79226048Sobrien{
80226048Sobrien
81226048Sobrien	return (crypt_format->name);
82226048Sobrien}
83226048Sobrien
84226048Sobrien/*
85226048Sobrien * Selects the format to use for subsequent crypt(3) invocations.
86226048Sobrien */
87226048Sobrienint
88226048Sobriencrypt_set_format(const char *format)
89226048Sobrien{
90226048Sobrien	const struct crypt_format *cf;
91226048Sobrien
92226048Sobrien	for (cf = crypt_formats; cf->name != NULL; ++cf) {
93226048Sobrien		if (strcasecmp(cf->name, format) == 0) {
94226048Sobrien			crypt_format = cf;
95226048Sobrien			return (1);
96226048Sobrien		}
97226048Sobrien	}
98226048Sobrien	return (0);
99226048Sobrien}
100226048Sobrien
101226048Sobrien/*
102226048Sobrien * Hash the given password with the given salt.  If the salt begins with a
103226048Sobrien * magic string (e.g. "$6$" for sha512), the corresponding format is used;
104226048Sobrien * otherwise, the currently selected format is used.
105226048Sobrien */
106267843Sdelphijchar *
107267843Sdelphijcrypt(const char *passwd, const char *salt)
108267843Sdelphij{
109267843Sdelphij	const struct crypt_format *cf;
110267843Sdelphij#ifdef HAS_DES
111267843Sdelphij	int len;
112267843Sdelphij#endif
113267843Sdelphij
114267843Sdelphij	for (cf = crypt_formats; cf->name != NULL; ++cf)
115267843Sdelphij		if (cf->magic != NULL && strstr(salt, cf->magic) == salt)
116267843Sdelphij			return (cf->func(passwd, salt));
117267843Sdelphij#ifdef HAS_DES
118	len = strlen(salt);
119	if ((len == 13 || len == 2) && strspn(salt, DES_SALT_ALPHABET) == len)
120		return (crypt_des(passwd, salt));
121#endif
122	return (crypt_format->func(passwd, salt));
123}
124