0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * CDDL HEADER START
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * The contents of this file are subject to the terms of the
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * Common Development and Distribution License (the "License").
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * You may not use this file except in compliance with the License.
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * See the License for the specific language governing permissions
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * and limitations under the License.
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * When distributing Covered Code, include this CDDL HEADER in each
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * If applicable, add the following below this CDDL HEADER, with the
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * fields enclosed by brackets "[]" replaced with your own identifying
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * information: Portions Copyright [yyyy] [name of copyright owner]
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * CDDL HEADER END
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * Use is subject to license terms.
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * Portions of this code from crypt_bsdmd5.so (bsdmd5.c) :
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * ----------------------------------------------------------------------------
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * "THE BEER-WARE LICENSE" (Revision 42):
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * can do whatever you want with this stuff. If we meet some day, and you think
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * ----------------------------------------------------------------------------
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * $FreeBSD: crypt.c,v 1.5 1996/10/14 08:34:02 phk Exp $
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * Implements the specification from:
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * From http://people.redhat.com/drepper/SHA-crypt.txt
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * Portions of the code taken from inspired by or verified against the
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * source in the above document which is licensed as:
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * "Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>."
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#error "One of CRYPT_256 or CRYPT_512 must be defined"
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllysstatic const int crypt_alg_magic_len = sizeof (crypt_alg_magic) - 1;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys int n = (N); \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys while (--n >= 0 && ctbufflen > 0) { \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys while (--n >= 0) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll * get the integer value after rounds= where ever it occurs in the string.
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll * if the last char after the int is a , or $ that is fine anything else is an
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll char *r, *p, *e;
1dbc1fed8be6e82e676ff3f124628dc470058bfbDan OpenSolaris Anderson * An error occurred or there is non-numeric stuff at the end
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll * which isn't one of the crypt(3c) special chars ',' or '$'
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char *plaintext,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char *switchsalt,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char **params)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* Refine the salt */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* skip our magic string */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (strncmp((char *)salt, crypt_alg_magic, crypt_alg_magic_len) == 0) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 2. The password first, since that is what is most unknown */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 3. Then the raw salt */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 4. - 8. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 9. - 10. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if ((i & 1) != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 13. - 15. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = 0; i < plaintext_len; i++)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = plaintext_len; i >= MIXCHARS; i -= MIXCHARS) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 17. - 19. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = 0; i < rounds; i++) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if ((i & 1) != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (i == 0)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (i % 3 != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (i % 7 != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if ((i & 1) != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (i == 0)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 22. Now make the output string */
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll "%s$rounds=%zu$", crypt_alg_magic, rounds);
20ed34cc7e9de957ef6251e20c0f2d8e43847ea0Wyllys Ingersoll (void) strncat(ctbuffer, (const char *)salt, salt_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys (void) memset(A, 0, sizeof (A));
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys (void) memset(B, 0, sizeof (B));
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char *oldsalt,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char **params)
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll for (i = 0; params != NULL && params[i] != NULL; i++) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (strncmp(params[i], ROUNDS, ROUNDSLEN) == 0) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll * If the config file has a higher value for rounds= than what
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll * was in the old salt use that, otherwise keep what was in the
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll to64((char *)&rndstr, rndval, sizeof (rndval));
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll "%s$rounds=%d$",
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (strlcat(gsbuffer, rndstr, gsbufflen) >= gsbufflen)