xcrypt.c revision 146841
150397Sobrien/*
290075Sobrien * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3169689Skan * unrestricted use provided that this legend is included on all tape
450397Sobrien * media and as a part of the software program in whole or part.  Users
550397Sobrien * may copy or modify Sun RPC without charge, but are not authorized
690075Sobrien * to license or distribute it to anyone else except as part of a product or
750397Sobrien * program developed by the user.
890075Sobrien *
990075Sobrien * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1090075Sobrien * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
1190075Sobrien * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1250397Sobrien *
1390075Sobrien * Sun RPC is provided with no support and without any obligation on the
1490075Sobrien * part of Sun Microsystems, Inc. to assist in its use, correction,
1590075Sobrien * modification or enhancement.
1690075Sobrien *
1750397Sobrien * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
1850397Sobrien * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
1990075Sobrien * OR ANY PART THEREOF.
20169689Skan *
21169689Skan * In no event will Sun Microsystems, Inc. be liable for any lost revenue
2250397Sobrien * or profits or other special, indirect and consequential damages, even if
2350397Sobrien * Sun has been advised of the possibility of such damages.
2450397Sobrien *
2550397Sobrien * Sun Microsystems, Inc.
2650397Sobrien * 2550 Garcia Avenue
2750397Sobrien * Mountain View, California  94043
2850397Sobrien */
2950397Sobrien/*
3050397Sobrien * Hex encryption/decryption and utility routines
3150397Sobrien *
3250397Sobrien * Copyright (C) 1986, Sun Microsystems, Inc.
3350397Sobrien */
3450397Sobrien
3550397Sobrien#include <sys/cdefs.h>
3650397Sobrien__FBSDID("$FreeBSD: head/lib/librpcsvc/xcrypt.c 146841 2005-05-31 21:19:14Z stefanf $");
3750397Sobrien
3850397Sobrien#include <stdio.h>
3950397Sobrien#include <stdlib.h>
4050397Sobrien#include <string.h>
4150397Sobrien#include <rpc/des_crypt.h>
4250397Sobrien
4350397Sobrienstatic char hex[16] = {
4450397Sobrien	'0', '1', '2', '3', '4', '5', '6', '7',
4550397Sobrien	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
4650397Sobrien};
4790075Sobrien
4850397Sobrienstatic char hexval( char );
4950397Sobrienstatic void bin2hex( int, unsigned char *, char * );
5090075Sobrienstatic void hex2bin( int, char *, char * );
5190075Sobrienvoid passwd2des( char *, char * );
52132718Skan
53132718Skan/*
5490075Sobrien * Encrypt a secret key given passwd
5590075Sobrien * The secret key is passed and returned in hex notation.
5690075Sobrien * Its length must be a multiple of 16 hex digits (64 bits).
5790075Sobrien */
5890075Sobrienint
5990075Sobrienxencrypt(secret, passwd)
6090075Sobrien	char *secret;
6190075Sobrien	char *passwd;
6290075Sobrien{
6390075Sobrien	char key[8];
6490075Sobrien	char ivec[8];
6590075Sobrien	char *buf;
6690075Sobrien	int err;
6790075Sobrien	int len;
6890075Sobrien
6990075Sobrien	len = strlen(secret) / 2;
7090075Sobrien	buf = malloc((unsigned)len);
7190075Sobrien
7290075Sobrien	hex2bin(len, secret, buf);
7390075Sobrien	passwd2des(passwd, key);
7490075Sobrien	bzero(ivec, 8);
75117395Skan
76132718Skan	err = cbc_crypt(key, buf, len, DES_ENCRYPT | DES_HW, ivec);
77169689Skan	if (DES_FAILED(err)) {
78169689Skan		free(buf);
79169689Skan		return (0);
8050397Sobrien	}
8190075Sobrien	bin2hex(len, (unsigned char *) buf, secret);
8290075Sobrien	free(buf);
8390075Sobrien	return (1);
8490075Sobrien}
8590075Sobrien
8650397Sobrien/*
8750397Sobrien * Decrypt secret key using passwd
8890075Sobrien * The secret key is passed and returned in hex notation.
8990075Sobrien * Once again, the length is a multiple of 16 hex digits
90132718Skan */
9150397Sobrienint
9290075Sobrienxdecrypt(secret, passwd)
93132718Skan	char *secret;
9450397Sobrien	char *passwd;
9590075Sobrien{
96132718Skan	char key[8];
9750397Sobrien	char ivec[8];
9896263Sobrien	char *buf;
9950397Sobrien	int err;
100117395Skan	int len;
10196263Sobrien
10296263Sobrien	len = strlen(secret) / 2;
10396263Sobrien	buf = malloc((unsigned)len);
10496263Sobrien
10596263Sobrien	hex2bin(len, secret, buf);
106132718Skan	passwd2des(passwd, key);
107117395Skan	bzero(ivec, 8);
108117395Skan
10950397Sobrien	err = cbc_crypt(key, buf, len, DES_DECRYPT | DES_HW, ivec);
11090075Sobrien	if (DES_FAILED(err)) {
111117395Skan		free(buf);
11290075Sobrien		return (0);
11390075Sobrien	}
11490075Sobrien	bin2hex(len, (unsigned char *) buf, secret);
11590075Sobrien	free(buf);
11690075Sobrien	return (1);
11790075Sobrien}
11890075Sobrien
119117395Skan
12090075Sobrien/*
12190075Sobrien * Turn password into DES key
12290075Sobrien */
12350397Sobrienvoid
12490075Sobrienpasswd2des(pw, key)
12590075Sobrien	char *pw;
12690075Sobrien	char *key;
12750397Sobrien{
12890075Sobrien	int i;
12990075Sobrien
13050397Sobrien	bzero(key, 8);
13196263Sobrien	for (i = 0; *pw; i = (i+1)%8) {
13296263Sobrien		key[i] ^= *pw++ << 1;
13396263Sobrien	}
13496263Sobrien	des_setparity(key);
13590075Sobrien}
13690075Sobrien
13790075Sobrien
13890075Sobrien
13990075Sobrien/*
14090075Sobrien * Hex to binary conversion
14190075Sobrien */
14290075Sobrienstatic void
14390075Sobrienhex2bin(len, hexnum, binnum)
144169689Skan	int len;
14590075Sobrien	char *hexnum;
14650397Sobrien	char *binnum;
14790075Sobrien{
148117395Skan	int i;
14990075Sobrien
15090075Sobrien	for (i = 0; i < len; i++) {
151117395Skan		*binnum++ = 16 * hexval(hexnum[2*i]) + hexval(hexnum[2*i+1]);
15290075Sobrien	}
15390075Sobrien}
154117395Skan
15550397Sobrien/*
15690075Sobrien * Binary to hex conversion
15790075Sobrien */
158117395Skanstatic void
15990075Sobrienbin2hex(len, binnum, hexnum)
16090075Sobrien	int len;
16190075Sobrien	unsigned char *binnum;
16290075Sobrien	char *hexnum;
163117395Skan{
16450397Sobrien	int i;
16590075Sobrien	unsigned val;
166117395Skan
16790075Sobrien	for (i = 0; i < len; i++) {
16890075Sobrien		val = binnum[i];
169117395Skan		hexnum[i*2] = hex[val >> 4];
17050397Sobrien		hexnum[i*2+1] = hex[val & 0xf];
17190075Sobrien	}
17290075Sobrien	hexnum[len*2] = 0;
173117395Skan}
17490075Sobrien
175117395Skanstatic char
17650397Sobrienhexval(c)
17790075Sobrien	char c;
17890075Sobrien{
179117395Skan	if (c >= '0' && c <= '9') {
180117395Skan		return (c - '0');
181117395Skan	} else if (c >= 'a' && c <= 'z') {
182117395Skan		return (c - 'a' + 10);
18350397Sobrien	} else if (c >= 'A' && c <= 'Z') {
18490075Sobrien		return (c - 'A' + 10);
18590075Sobrien	} else {
186169689Skan		return (-1);
18750397Sobrien	}
18890075Sobrien}
18990075Sobrien