xcrypt.c revision 84220
1178825Sdfr/*
2178825Sdfr * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3178825Sdfr * unrestricted use provided that this legend is included on all tape
4178825Sdfr * media and as a part of the software program in whole or part.  Users
5233294Sstas * may copy or modify Sun RPC without charge, but are not authorized
6233294Sstas * to license or distribute it to anyone else except as part of a product or
7178825Sdfr * program developed by the user.
8178825Sdfr *
9178825Sdfr * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10178825Sdfr * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11178825Sdfr * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12178825Sdfr *
13178825Sdfr * Sun RPC is provided with no support and without any obligation on the
14178825Sdfr * part of Sun Microsystems, Inc. to assist in its use, correction,
15178825Sdfr * modification or enhancement.
16178825Sdfr *
17178825Sdfr * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18178825Sdfr * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19178825Sdfr * OR ANY PART THEREOF.
20178825Sdfr *
21178825Sdfr * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22178825Sdfr * or profits or other special, indirect and consequential damages, even if
23178825Sdfr * Sun has been advised of the possibility of such damages.
24178825Sdfr *
25178825Sdfr * Sun Microsystems, Inc.
26178825Sdfr * 2550 Garcia Avenue
27178825Sdfr * Mountain View, California  94043
28178825Sdfr */
29178825Sdfr/*
30178825Sdfr * Hex encryption/decryption and utility routines
31178825Sdfr *
32178825Sdfr * Copyright (C) 1986, Sun Microsystems, Inc.
33178825Sdfr */
34178825Sdfr
35178825Sdfr#include <sys/cdefs.h>
36233294Sstas__FBSDID("$FreeBSD: head/lib/librpcsvc/xcrypt.c 84220 2001-09-30 22:15:15Z dillon $");
37178825Sdfr
38233294Sstas#include <stdio.h>
39233294Sstas#include <stdlib.h>
40178825Sdfr#include <string.h>
41233294Sstas#include <rpc/des_crypt.h>
42233294Sstas
43233294Sstasstatic char hex[];	/* forward */
44233294Sstasstatic char hexval __P(( char ));
45233294Sstasstatic void bin2hex __P(( int, unsigned char *, char * ));
46233294Sstasstatic void hex2bin __P(( int, char *, char * ));
47233294Sstasvoid passwd2des __P(( char *, char * ));
48233294Sstas
49233294Sstas/*
50233294Sstas * Encrypt a secret key given passwd
51233294Sstas * The secret key is passed and returned in hex notation.
52233294Sstas * Its length must be a multiple of 16 hex digits (64 bits).
53178825Sdfr */
54178825Sdfrint
55178825Sdfrxencrypt(secret, passwd)
56178825Sdfr	char *secret;
57178825Sdfr	char *passwd;
58178825Sdfr{
59178825Sdfr	char key[8];
60178825Sdfr	char ivec[8];
61178825Sdfr	char *buf;
62233294Sstas	int err;
63178825Sdfr	int len;
64178825Sdfr
65178825Sdfr	len = strlen(secret) / 2;
66178825Sdfr	buf = malloc((unsigned)len);
67178825Sdfr
68178825Sdfr	hex2bin(len, secret, buf);
69178825Sdfr	passwd2des(passwd, key);
70178825Sdfr	bzero(ivec, 8);
71178825Sdfr
72178825Sdfr	err = cbc_crypt(key, buf, len, DES_ENCRYPT | DES_HW, ivec);
73178825Sdfr	if (DES_FAILED(err)) {
74178825Sdfr		free(buf);
75178825Sdfr		return (0);
76178825Sdfr	}
77178825Sdfr	bin2hex(len, (unsigned char *) buf, secret);
78178825Sdfr	free(buf);
79178825Sdfr	return (1);
80178825Sdfr}
81178825Sdfr
82178825Sdfr/*
83178825Sdfr * Decrypt secret key using passwd
84178825Sdfr * The secret key is passed and returned in hex notation.
85178825Sdfr * Once again, the length is a multiple of 16 hex digits
86178825Sdfr */
87178825Sdfrint
88178825Sdfrxdecrypt(secret, passwd)
89178825Sdfr	char *secret;
90178825Sdfr	char *passwd;
91178825Sdfr{
92178825Sdfr	char key[8];
93178825Sdfr	char ivec[8];
94178825Sdfr	char *buf;
95178825Sdfr	int err;
96178825Sdfr	int len;
97178825Sdfr
98178825Sdfr	len = strlen(secret) / 2;
99233294Sstas	buf = malloc((unsigned)len);
100178825Sdfr
101178825Sdfr	hex2bin(len, secret, buf);
102178825Sdfr	passwd2des(passwd, key);
103178825Sdfr	bzero(ivec, 8);
104178825Sdfr
105233294Sstas	err = cbc_crypt(key, buf, len, DES_DECRYPT | DES_HW, ivec);
106178825Sdfr	if (DES_FAILED(err)) {
107178825Sdfr		free(buf);
108178825Sdfr		return (0);
109178825Sdfr	}
110178825Sdfr	bin2hex(len, (unsigned char *) buf, secret);
111233294Sstas	free(buf);
112178825Sdfr	return (1);
113178825Sdfr}
114178825Sdfr
115178825Sdfr
116178825Sdfr/*
117178825Sdfr * Turn password into DES key
118178825Sdfr */
119178825Sdfrvoid
120178825Sdfrpasswd2des(pw, key)
121178825Sdfr	char *pw;
122178825Sdfr	char *key;
123178825Sdfr{
124178825Sdfr	int i;
125178825Sdfr
126178825Sdfr	bzero(key, 8);
127178825Sdfr	for (i = 0; *pw; i = (i+1)%8) {
128178825Sdfr		key[i] ^= *pw++ << 1;
129178825Sdfr	}
130178825Sdfr	des_setparity(key);
131178825Sdfr}
132178825Sdfr
133178825Sdfr
134178825Sdfr
135178825Sdfr/*
136178825Sdfr * Hex to binary conversion
137178825Sdfr */
138178825Sdfrstatic void
139178825Sdfrhex2bin(len, hexnum, binnum)
140178825Sdfr	int len;
141178825Sdfr	char *hexnum;
142233294Sstas	char *binnum;
143178825Sdfr{
144233294Sstas	int i;
145178825Sdfr
146178825Sdfr	for (i = 0; i < len; i++) {
147178825Sdfr		*binnum++ = 16 * hexval(hexnum[2*i]) + hexval(hexnum[2*i+1]);
148178825Sdfr	}
149178825Sdfr}
150178825Sdfr
151178825Sdfr/*
152178825Sdfr * Binary to hex conversion
153178825Sdfr */
154178825Sdfrstatic void
155178825Sdfrbin2hex(len, binnum, hexnum)
156178825Sdfr	int len;
157178825Sdfr	unsigned char *binnum;
158178825Sdfr	char *hexnum;
159178825Sdfr{
160178825Sdfr	int i;
161178825Sdfr	unsigned val;
162178825Sdfr
163178825Sdfr	for (i = 0; i < len; i++) {
164178825Sdfr		val = binnum[i];
165178825Sdfr		hexnum[i*2] = hex[val >> 4];
166178825Sdfr		hexnum[i*2+1] = hex[val & 0xf];
167178825Sdfr	}
168178825Sdfr	hexnum[len*2] = 0;
169178825Sdfr}
170178825Sdfr
171178825Sdfrstatic char hex[16] = {
172178825Sdfr	'0', '1', '2', '3', '4', '5', '6', '7',
173178825Sdfr	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
174178825Sdfr};
175178825Sdfr
176178825Sdfrstatic char
177178825Sdfrhexval(c)
178178825Sdfr	char c;
179178825Sdfr{
180178825Sdfr	if (c >= '0' && c <= '9') {
181178825Sdfr		return (c - '0');
182178825Sdfr	} else if (c >= 'a' && c <= 'z') {
183178825Sdfr		return (c - 'a' + 10);
184178825Sdfr	} else if (c >= 'A' && c <= 'Z') {
185178825Sdfr		return (c - 'A' + 10);
186178825Sdfr	} else {
187178825Sdfr		return (-1);
188178825Sdfr	}
189178825Sdfr}
190178825Sdfr