1258578Shrs/*-
2258578Shrs * Copyright (c) 2009, Sun Microsystems, Inc.
3258578Shrs * All rights reserved.
4258578Shrs *
5258578Shrs * Redistribution and use in source and binary forms, with or without
6258578Shrs * modification, are permitted provided that the following conditions are met:
7258578Shrs * - Redistributions of source code must retain the above copyright notice,
8258578Shrs *   this list of conditions and the following disclaimer.
9258578Shrs * - Redistributions in binary form must reproduce the above copyright notice,
10258578Shrs *   this list of conditions and the following disclaimer in the documentation
11258578Shrs *   and/or other materials provided with the distribution.
12258578Shrs * - Neither the name of Sun Microsystems, Inc. nor the names of its
13258578Shrs *   contributors may be used to endorse or promote products derived
14258578Shrs *   from this software without specific prior written permission.
1526219Swpaul *
16258578Shrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17258578Shrs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18258578Shrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19258578Shrs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20258578Shrs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21258578Shrs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22258578Shrs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23258578Shrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24258578Shrs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25258578Shrs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26258578Shrs * POSSIBILITY OF SUCH DAMAGE.
2726219Swpaul */
2826219Swpaul/*
2926219Swpaul * des_crypt.c, DES encryption library routines
3026219Swpaul * Copyright (C) 1986, Sun Microsystems, Inc.
3126219Swpaul */
3226219Swpaul
3326219Swpaul#include <sys/types.h>
3426219Swpaul#include <rpc/des_crypt.h>
3526219Swpaul#include <rpc/des.h>
3626219Swpaul
37136581Sobrien#if defined(LIBC_SCCS) && !defined(lint)
3892990Sobrienstatic char sccsid[] = "@(#)des_crypt.c	2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
3926219Swpaul#endif
4092990Sobrien#include <sys/cdefs.h>
4192990Sobrien__FBSDID("$FreeBSD: releng/11.0/lib/libc/rpc/des_crypt.c 288113 2015-09-22 15:40:07Z rodrigc $");
4226219Swpaul
4392905Sobrienstatic int common_crypt( char *, char *, unsigned, unsigned, struct desparams * );
44288113Srodrigcint (*__des_crypt_LOCAL)(char *, unsigned, struct desparams *) = 0;
4592905Sobrienextern int _des_crypt_call(char *, int, struct desparams *);
4626219Swpaul/*
4726219Swpaul * Copy 8 bytes
4826219Swpaul */
4926219Swpaul#define COPY8(src, dst) { \
5092889Sobrien	char *a = (char *) dst; \
5192889Sobrien	char *b = (char *) src; \
5226219Swpaul	*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
5326219Swpaul	*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
5426219Swpaul}
5526219Swpaul
5626219Swpaul/*
5726219Swpaul * Copy multiple of 8 bytes
5826219Swpaul */
5926219Swpaul#define DESCOPY(src, dst, len) { \
6092889Sobrien	char *a = (char *) dst; \
6192889Sobrien	char *b = (char *) src; \
6292889Sobrien	int i; \
6326219Swpaul	for (i = (int) len; i > 0; i -= 8) { \
6426219Swpaul		*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
6526219Swpaul		*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
6626219Swpaul	} \
6726219Swpaul}
6826219Swpaul
6926219Swpaul/*
7026219Swpaul * CBC mode encryption
7126219Swpaul */
7226219Swpaulint
73287341Srodrigccbc_crypt(char *key, char *buf, unsigned len, unsigned mode, char *ivec)
7426219Swpaul{
7526219Swpaul	int err;
7626219Swpaul	struct desparams dp;
7726219Swpaul
7826219Swpaul#ifdef BROKEN_DES
7926219Swpaul	dp.UDES.UDES_buf = buf;
8026219Swpaul	dp.des_mode = ECB;
8126219Swpaul#else
8226219Swpaul	dp.des_mode = CBC;
8326219Swpaul#endif
8426219Swpaul	COPY8(ivec, dp.des_ivec);
8526219Swpaul	err = common_crypt(key, buf, len, mode, &dp);
8626219Swpaul	COPY8(dp.des_ivec, ivec);
8726219Swpaul	return(err);
8826219Swpaul}
8926219Swpaul
9026219Swpaul
9126219Swpaul/*
9226219Swpaul * ECB mode encryption
9326219Swpaul */
9426219Swpaulint
95287341Srodrigcecb_crypt(char *key, char *buf, unsigned len, unsigned mode)
9626219Swpaul{
9726219Swpaul	struct desparams dp;
9826219Swpaul
9926219Swpaul#ifdef BROKEN_DES
10026219Swpaul	dp.UDES.UDES_buf = buf;
10126219Swpaul	dp.des_mode = CBC;
10226219Swpaul#else
10326219Swpaul	dp.des_mode = ECB;
10426219Swpaul#endif
10526219Swpaul	return(common_crypt(key, buf, len, mode, &dp));
10626219Swpaul}
10726219Swpaul
10826219Swpaul
10926219Swpaul
11026219Swpaul/*
11126219Swpaul * Common code to cbc_crypt() & ecb_crypt()
11226219Swpaul */
11326219Swpaulstatic int
114287341Srodrigccommon_crypt(char *key, char *buf, unsigned len, unsigned mode,
115287341Srodrigc    struct desparams *desp)
11626219Swpaul{
11792889Sobrien	int desdev;
11826219Swpaul
11926219Swpaul	if ((len % 8) != 0 || len > DES_MAXDATA) {
12026219Swpaul		return(DESERR_BADPARAM);
12126219Swpaul	}
12226219Swpaul	desp->des_dir =
12326219Swpaul		((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
12426219Swpaul
12526219Swpaul	desdev = mode & DES_DEVMASK;
12626219Swpaul	COPY8(key, desp->des_key);
12726219Swpaul	/*
12826219Swpaul	 * software
12926219Swpaul	 */
13026219Swpaul	if (__des_crypt_LOCAL != NULL) {
13126219Swpaul		if (!__des_crypt_LOCAL(buf, len, desp)) {
13226219Swpaul			return (DESERR_HWERROR);
13326219Swpaul		}
13426219Swpaul	} else {
13526219Swpaul		if (!_des_crypt_call(buf, len, desp)) {
13626219Swpaul			return (DESERR_HWERROR);
13726219Swpaul		}
13826219Swpaul	}
13926219Swpaul	return(desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
14026219Swpaul}
141