0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys/*
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * CDDL HEADER START
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys *
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 *
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * or http://www.opensolaris.org/os/licensing.
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * See the License for the specific language governing permissions
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * and limitations under the License.
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys *
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 *
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * CDDL HEADER END
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys/*
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * Use is subject to license terms.
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys/*
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 *
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * $FreeBSD: crypt.c,v 1.5 1996/10/14 08:34:02 phk Exp $
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys *
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys/*
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * Implements the specification from:
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys *
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * From http://people.redhat.com/drepper/SHA-crypt.txt
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys *
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * Portions of the code taken from inspired by or verified against the
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * source in the above document which is licensed as:
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys *
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys * "Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>."
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <sys/types.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <sys/stat.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <sys/sysmacros.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <fcntl.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <unistd.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <string.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <stdio.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <errno.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <stdlib.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <alloca.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <sha2.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#include <crypt.h>
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define MAX_SALT_LEN 16
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define ROUNDS_DEFAULT 5000
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define ROUNDS_MIN 1000
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define ROUNDS_MAX 999999999
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#ifdef CRYPT_SHA256
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGEST_CTX SHA256_CTX
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGESTInit SHA256Init
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGESTUpdate SHA256Update
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGESTFinal SHA256Final
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGEST_LEN SHA256_DIGEST_LENGTH
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define MIXCHARS 32
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersollstatic const char crypt_alg_magic[] = "$5";
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#elif CRYPT_SHA512
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGEST_CTX SHA512_CTX
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGESTInit SHA512Init
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGESTUpdate SHA512Update
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGESTFinal SHA512Final
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define DIGEST_LEN SHA512_DIGEST_LENGTH
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define MIXCHARS 64
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersollstatic const char crypt_alg_magic[] = "$6";
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#else
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#error "One of CRYPT_256 or CRYPT_512 must be defined"
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#endif
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllysstatic const int crypt_alg_magic_len = sizeof (crypt_alg_magic) - 1;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllysstatic uchar_t b64t[] = /* 0 ... 63 => ascii - 64 */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#define b64_from_24bit(B2, B1, B0, N) \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys{ \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys uint_t w = ((B2) << 16) | ((B1) << 8) | (B0); \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys int n = (N); \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys while (--n >= 0 && ctbufflen > 0) { \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys *p++ = b64t[w & 0x3f]; \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys w >>= 6; \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys ctbufflen--; \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys } \
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys}
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllysstatic void
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllysto64(char *s, uint64_t v, int n)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys{
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys while (--n >= 0) {
1dbc1fed8be6e82e676ff3f124628dc470058bfbDan OpenSolaris Anderson *s++ = b64t[v & 0x3f];
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys v >>= 6;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys}
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll#define ROUNDS "rounds="
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll#define ROUNDSLEN (sizeof (ROUNDS) - 1)
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll/*
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 * error.
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll */
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersollstatic uint32_t
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersollgetrounds(const char *s)
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll{
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll char *r, *p, *e;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll long val;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (s == NULL)
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll return (0);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if ((r = strstr(s, ROUNDS)) == NULL) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll return (0);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll }
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (strncmp(r, ROUNDS, ROUNDSLEN) != 0) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll return (0);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll }
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll p = r + ROUNDSLEN;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll errno = 0;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll val = strtol(p, &e, 10);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll /*
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 '$'
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll */
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (errno != 0 || val < 0 ||
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll !(*e == '\0' || *e == ',' || *e == '$')) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll return (0);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll }
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll return ((uint32_t)val);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll}
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
1dbc1fed8be6e82e676ff3f124628dc470058bfbDan OpenSolaris Anderson/* ARGSUSED4 */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllyschar *
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllyscrypt_genhash_impl(char *ctbuffer,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys size_t ctbufflen,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char *plaintext,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char *switchsalt,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char **params)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys{
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys int salt_len, plaintext_len, i;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys char *salt;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys uchar_t A[DIGEST_LEN];
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys uchar_t B[DIGEST_LEN];
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys uchar_t DP[DIGEST_LEN];
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys uchar_t DS[DIGEST_LEN];
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGEST_CTX ctxA, ctxB, ctxC, ctxDP, ctxDS;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys int rounds = ROUNDS_DEFAULT;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll int srounds = 0;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys boolean_t custom_rounds = B_FALSE;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys char *p;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys char *P, *Pp;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys char *S, *Sp;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* Refine the salt */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys salt = (char *)switchsalt;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* skip our magic string */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (strncmp((char *)salt, crypt_alg_magic, crypt_alg_magic_len) == 0) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll salt += crypt_alg_magic_len + 1;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll srounds = getrounds(salt);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (srounds != 0) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll custom_rounds = B_TRUE;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll p = strchr(salt, '$');
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (p != NULL)
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll salt = p + 1;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys salt_len = MIN(strcspn(salt, "$"), MAX_SALT_LEN);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys plaintext_len = strlen(plaintext);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 1. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTInit(&ctxA);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 2. The password first, since that is what is most unknown */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxA, plaintext, plaintext_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 3. Then the raw salt */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxA, salt, salt_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 4. - 8. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTInit(&ctxB);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxB, plaintext, plaintext_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxB, salt, salt_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxB, plaintext, plaintext_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTFinal(B, &ctxB);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 9. - 10. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = plaintext_len; i > MIXCHARS; i -= MIXCHARS)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxA, B, MIXCHARS);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxA, B, i);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 11. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = plaintext_len; i > 0; i >>= 1) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if ((i & 1) != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxA, B, MIXCHARS);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys } else {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxA, plaintext, plaintext_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 12. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTFinal(A, &ctxA);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 13. - 15. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTInit(&ctxDP);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = 0; i < plaintext_len; i++)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxDP, plaintext, plaintext_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTFinal(DP, &ctxDP);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 16. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys Pp = P = alloca(plaintext_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = plaintext_len; i >= MIXCHARS; i -= MIXCHARS) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys Pp = (char *)(memcpy(Pp, DP, MIXCHARS)) + MIXCHARS;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
1dbc1fed8be6e82e676ff3f124628dc470058bfbDan OpenSolaris Anderson (void) memcpy(Pp, DP, i);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 17. - 19. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTInit(&ctxDS);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = 0; i < 16 + (uint8_t)A[0]; i++)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxDS, salt, salt_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTFinal(DS, &ctxDS);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 20. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys Sp = S = alloca(salt_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = salt_len; i >= MIXCHARS; i -= MIXCHARS) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys Sp = (char *)(memcpy(Sp, DS, MIXCHARS)) + MIXCHARS;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
1dbc1fed8be6e82e676ff3f124628dc470058bfbDan OpenSolaris Anderson (void) memcpy(Sp, DS, i);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 21. */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys for (i = 0; i < rounds; i++) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTInit(&ctxC);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if ((i & 1) != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxC, P, plaintext_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys } else {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (i == 0)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxC, A, MIXCHARS);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys else
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxC, DP, MIXCHARS);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (i % 3 != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxC, S, salt_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (i % 7 != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxC, P, plaintext_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if ((i & 1) != 0) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (i == 0)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxC, A, MIXCHARS);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys else
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxC, DP, MIXCHARS);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys } else {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTUpdate(&ctxC, P, plaintext_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys DIGESTFinal(DP, &ctxC);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys /* 22. Now make the output string */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (custom_rounds) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys (void) snprintf(ctbuffer, ctbufflen,
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll "%s$rounds=%zu$", crypt_alg_magic, rounds);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll } else {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll (void) snprintf(ctbuffer, ctbufflen,
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll "%s$", crypt_alg_magic);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
20ed34cc7e9de957ef6251e20c0f2d8e43847ea0Wyllys Ingersoll (void) strncat(ctbuffer, (const char *)salt, salt_len);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys (void) strlcat(ctbuffer, "$", ctbufflen);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys p = ctbuffer + strlen(ctbuffer);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys ctbufflen -= strlen(ctbuffer);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#ifdef CRYPT_SHA256
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[ 0], DP[10], DP[20], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[21], DP[ 1], DP[11], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[12], DP[22], DP[ 2], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[ 3], DP[13], DP[23], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[24], DP[ 4], DP[14], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[15], DP[25], DP[ 5], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[ 6], DP[16], DP[26], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[27], DP[ 7], DP[17], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[18], DP[28], DP[ 8], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[ 9], DP[19], DP[29], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(0, DP[31], DP[30], 3);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#elif CRYPT_SHA512
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[ 0], DP[21], DP[42], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[22], DP[43], DP[ 1], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[44], DP[ 2], DP[23], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[ 3], DP[24], DP[45], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[25], DP[46], DP[ 4], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[47], DP[ 5], DP[26], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[ 6], DP[27], DP[48], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[28], DP[49], DP[ 7], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[50], DP[ 8], DP[29], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[ 9], DP[30], DP[51], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[31], DP[52], DP[10], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[53], DP[11], DP[32], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[12], DP[33], DP[54], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[34], DP[55], DP[13], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[56], DP[14], DP[35], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[15], DP[36], DP[57], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[37], DP[58], DP[16], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[59], DP[17], DP[38], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[18], DP[39], DP[60], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[40], DP[61], DP[19], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(DP[62], DP[20], DP[41], 4);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys b64_from_24bit(0, 0, DP[63], 2);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys#endif
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys *p = '\0';
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys (void) memset(A, 0, sizeof (A));
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys (void) memset(B, 0, sizeof (B));
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys (void) memset(DP, 0, sizeof (DP));
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys (void) memset(DS, 0, sizeof (DS));
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys return (ctbuffer);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys}
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
1dbc1fed8be6e82e676ff3f124628dc470058bfbDan OpenSolaris Anderson
1dbc1fed8be6e82e676ff3f124628dc470058bfbDan OpenSolaris Anderson/* ARGSUSED3 */
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllyschar *
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllyscrypt_gensalt_impl(char *gsbuffer,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys size_t gsbufflen,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char *oldsalt,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const struct passwd *userinfo,
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys const char **params)
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys{
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys int fd;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys int err;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys ssize_t got;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys uint64_t rndval;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll uint32_t confrounds = 0;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll uint32_t saltrounds;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll char rndstr[sizeof (rndval) + 1];
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll int i;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll for (i = 0; params != NULL && params[i] != NULL; i++) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (strncmp(params[i], ROUNDS, ROUNDSLEN) == 0) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll confrounds = getrounds(params[i]);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll } else {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll errno = EINVAL;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll return (NULL);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll }
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll }
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll /*
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 * old salt.
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll */
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll saltrounds = getrounds(oldsalt);
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (confrounds > saltrounds) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll saltrounds = confrounds;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if ((fd = open("/dev/urandom", O_RDONLY)) == -1) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys return (NULL);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys got = read(fd, &rndval, sizeof (rndval));
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys if (got < sizeof (rndval)) {
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys err = errno;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys (void) close(fd);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys errno = err;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys return (NULL);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys }
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll (void) close(fd);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll to64((char *)&rndstr, rndval, sizeof (rndval));
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll rndstr[sizeof (rndstr) - 1] = 0;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (saltrounds > 0) {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (snprintf(gsbuffer, gsbufflen,
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll "%s$rounds=%d$",
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll crypt_alg_magic, saltrounds) >= gsbufflen)
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll goto fail;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll } else {
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (snprintf(gsbuffer, gsbufflen,
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll "%s$", crypt_alg_magic) >= gsbufflen)
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll goto fail;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll }
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (strlcat(gsbuffer, rndstr, gsbufflen) >= gsbufflen)
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll goto fail;
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll if (strlcat(gsbuffer, "$", gsbufflen) >= gsbufflen)
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll goto fail;
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll return (gsbuffer);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersollfail:
0ca46ac5a61f0a757ca72f469fdbb1859c3fa490Wyllys Ingersoll (void) memset(gsbuffer, 0, gsbufflen);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys return (gsbuffer);
0cd13cbfb4270b840b4bd22ec5f673b2b6a2c02bwyllys}