crypt.c revision 261913
1240116Smarcel/*
2240116Smarcel * Copyright (c) 1999
3240116Smarcel *      Mark Murray.  All rights reserved.
4240116Smarcel *
5240116Smarcel * Redistribution and use in source and binary forms, with or without
6240116Smarcel * modification, are permitted provided that the following conditions
7240116Smarcel * are met:
8240116Smarcel * 1. Redistributions of source code must retain the above copyright
9240116Smarcel *    notice, this list of conditions and the following disclaimer.
10240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright
11240116Smarcel *    notice, this list of conditions and the following disclaimer in the
12240116Smarcel *    documentation and/or other materials provided with the distribution.
13240116Smarcel *
14240116Smarcel * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND
15240116Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16240116Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17240116Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL MARK MURRAY OR CONTRIBUTORS BE LIABLE
18240116Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20240116Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21240116Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22240116Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23240116Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24240116Smarcel * SUCH DAMAGE.
25240116Smarcel */
26275988Sngie
27275988Sngie#include <sys/cdefs.h>
28240116Smarcel__FBSDID("$FreeBSD: head/lib/libcrypt/crypt.c 261913 2014-02-15 10:53:44Z des $");
29240116Smarcel
30240116Smarcel#include <sys/types.h>
31240116Smarcel#include <string.h>
32240116Smarcel#include <libutil.h>
33275988Sngie#include <unistd.h>
34240116Smarcel#include "crypt.h"
35275988Sngie
36275988Sngiestatic const struct {
37275988Sngie	const char *const name;
38275988Sngie	char *(*const func)(const char *, const char *);
39240116Smarcel	const char *const magic;
40262849Sjmmv} crypt_types[] = {
41262849Sjmmv#ifdef HAS_DES
42262849Sjmmv	{
43262849Sjmmv		"des",
44262849Sjmmv		crypt_des,
45262849Sjmmv		NULL
46262849Sjmmv	},
47262849Sjmmv#endif
48262849Sjmmv	{
49262849Sjmmv		"md5",
50262849Sjmmv		crypt_md5,
51262849Sjmmv		"$1$"
52262855Sjmmv	},
53262855Sjmmv#ifdef HAS_BLOWFISH
54240116Smarcel	{
55240116Smarcel		"blf",
56275988Sngie		crypt_blowfish,
57240116Smarcel		"$2"
58240116Smarcel	},
59240116Smarcel#endif
60262855Sjmmv	{
61262855Sjmmv		"nth",
62240116Smarcel		crypt_nthash,
63240116Smarcel		"$3$"
64262855Sjmmv	},
65262855Sjmmv	{
66240116Smarcel		"sha256",
67240116Smarcel		crypt_sha256,
68240116Smarcel		"$5$"
69262855Sjmmv	},
70240116Smarcel	{
71240116Smarcel		"sha512",
72240116Smarcel		crypt_sha512,
73240116Smarcel		"$6$"
74240116Smarcel	},
75260578Sjmmv	{
76240116Smarcel		NULL,
77240116Smarcel		NULL,
78240116Smarcel		NULL
79240116Smarcel	}
80240116Smarcel};
81240116Smarcel
82262855Sjmmv#define CRYPT_DEFAULT	"sha512"
83262855Sjmmv
84240116Smarcelstatic int crypt_type = -1;
85240116Smarcel
86240116Smarcelstatic void
87251108Smarcelcrypt_setdefault(void)
88240116Smarcel{
89262849Sjmmv	size_t i;
90262849Sjmmv
91262849Sjmmv	if (crypt_type != -1)
92262849Sjmmv		return;
93262849Sjmmv	for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) {
94262849Sjmmv		if (strcmp(CRYPT_DEFAULT, crypt_types[i].name) == 0) {
95262849Sjmmv			crypt_type = (int)i;
96262849Sjmmv			return;
97262849Sjmmv		}
98262849Sjmmv	}
99262849Sjmmv	crypt_type = 0;
100240116Smarcel}
101
102const char *
103crypt_get_format(void)
104{
105
106	crypt_setdefault();
107	return (crypt_types[crypt_type].name);
108}
109
110int
111crypt_set_format(const char *type)
112{
113	size_t i;
114
115	crypt_setdefault();
116	for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) {
117		if (strcmp(type, crypt_types[i].name) == 0) {
118			crypt_type = (int)i;
119			return (1);
120		}
121	}
122	return (0);
123}
124
125char *
126crypt(const char *passwd, const char *salt)
127{
128	size_t i;
129
130	crypt_setdefault();
131	for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) {
132		if (crypt_types[i].magic != NULL && strncmp(salt,
133		    crypt_types[i].magic, strlen(crypt_types[i].magic)) == 0)
134			return (crypt_types[i].func(passwd, salt));
135	}
136	return (crypt_types[crypt_type].func(passwd, salt));
137}
138