126213Swpaul/*
226213Swpaul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
326213Swpaul * unrestricted use provided that this legend is included on all tape
426213Swpaul * media and as a part of the software program in whole or part.  Users
526213Swpaul * may copy or modify Sun RPC without charge, but are not authorized
626213Swpaul * to license or distribute it to anyone else except as part of a product or
726213Swpaul * program developed by the user.
826213Swpaul *
926213Swpaul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1026213Swpaul * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
1126213Swpaul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1226213Swpaul *
1326213Swpaul * Sun RPC is provided with no support and without any obligation on the
1426213Swpaul * part of Sun Microsystems, Inc. to assist in its use, correction,
1526213Swpaul * modification or enhancement.
1626213Swpaul *
1726213Swpaul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
1826213Swpaul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
1926213Swpaul * OR ANY PART THEREOF.
2026213Swpaul *
2126213Swpaul * In no event will Sun Microsystems, Inc. be liable for any lost revenue
2226213Swpaul * or profits or other special, indirect and consequential damages, even if
2326213Swpaul * Sun has been advised of the possibility of such damages.
2426213Swpaul *
2526213Swpaul * Sun Microsystems, Inc.
2626213Swpaul * 2550 Garcia Avenue
2726213Swpaul * Mountain View, California  94043
2826213Swpaul */
2926213Swpaul/*
3026213Swpaul * Hex encryption/decryption and utility routines
3126213Swpaul *
3226213Swpaul * Copyright (C) 1986, Sun Microsystems, Inc.
3326213Swpaul */
3426213Swpaul
3584220Sdillon#include <sys/cdefs.h>
3684220Sdillon__FBSDID("$FreeBSD$");
3784220Sdillon
3826213Swpaul#include <stdio.h>
3926213Swpaul#include <stdlib.h>
4026213Swpaul#include <string.h>
4126213Swpaul#include <rpc/des_crypt.h>
4226213Swpaul
43146841Sstefanfstatic char hex[16] = {
44146841Sstefanf	'0', '1', '2', '3', '4', '5', '6', '7',
45146841Sstefanf	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
46146841Sstefanf};
47146841Sstefanf
4892917Sobrienstatic char hexval( char );
4992917Sobrienstatic void bin2hex( int, unsigned char *, char * );
5092917Sobrienstatic void hex2bin( int, char *, char * );
5192917Sobrienvoid passwd2des( char *, char * );
5226213Swpaul
5326213Swpaul/*
5426213Swpaul * Encrypt a secret key given passwd
5526213Swpaul * The secret key is passed and returned in hex notation.
5626213Swpaul * Its length must be a multiple of 16 hex digits (64 bits).
5726213Swpaul */
5826213Swpaulint
59189087Sedxencrypt(char *secret, char *passwd)
6026213Swpaul{
6126213Swpaul	char key[8];
6226213Swpaul	char ivec[8];
6326213Swpaul	char *buf;
6426213Swpaul	int err;
6526213Swpaul	int len;
6626213Swpaul
6726213Swpaul	len = strlen(secret) / 2;
68175965Smatteo	if ((buf = malloc((unsigned)len)) == NULL) {
69175965Smatteo		return(0);
70175965Smatteo	}
7126213Swpaul
7226213Swpaul	hex2bin(len, secret, buf);
7326213Swpaul	passwd2des(passwd, key);
7426213Swpaul	bzero(ivec, 8);
7526213Swpaul
7626213Swpaul	err = cbc_crypt(key, buf, len, DES_ENCRYPT | DES_HW, ivec);
7726213Swpaul	if (DES_FAILED(err)) {
7826213Swpaul		free(buf);
7926213Swpaul		return (0);
8026213Swpaul	}
8126213Swpaul	bin2hex(len, (unsigned char *) buf, secret);
8226213Swpaul	free(buf);
8326213Swpaul	return (1);
8426213Swpaul}
8526213Swpaul
8626213Swpaul/*
8726213Swpaul * Decrypt secret key using passwd
8826213Swpaul * The secret key is passed and returned in hex notation.
8926213Swpaul * Once again, the length is a multiple of 16 hex digits
9026213Swpaul */
9126213Swpaulint
92189087Sedxdecrypt(char *secret, char *passwd)
9326213Swpaul{
9426213Swpaul	char key[8];
9526213Swpaul	char ivec[8];
9626213Swpaul	char *buf;
9726213Swpaul	int err;
9826213Swpaul	int len;
9926213Swpaul
10026213Swpaul	len = strlen(secret) / 2;
101175965Smatteo	if ((buf = malloc((unsigned)len)) == NULL) {
102175965Smatteo		return(0);
103175965Smatteo	}
10426213Swpaul
10526213Swpaul	hex2bin(len, secret, buf);
10626213Swpaul	passwd2des(passwd, key);
10726213Swpaul	bzero(ivec, 8);
10826213Swpaul
10926213Swpaul	err = cbc_crypt(key, buf, len, DES_DECRYPT | DES_HW, ivec);
11026213Swpaul	if (DES_FAILED(err)) {
11126213Swpaul		free(buf);
11226213Swpaul		return (0);
11326213Swpaul	}
11426213Swpaul	bin2hex(len, (unsigned char *) buf, secret);
11526213Swpaul	free(buf);
11626213Swpaul	return (1);
11726213Swpaul}
11826213Swpaul
11926213Swpaul
12026213Swpaul/*
12126213Swpaul * Turn password into DES key
12226213Swpaul */
12326213Swpaulvoid
124189087Sedpasswd2des(char *pw, char *key)
12526213Swpaul{
12626213Swpaul	int i;
12726213Swpaul
12826213Swpaul	bzero(key, 8);
12926213Swpaul	for (i = 0; *pw; i = (i+1)%8) {
13026213Swpaul		key[i] ^= *pw++ << 1;
13126213Swpaul	}
13226213Swpaul	des_setparity(key);
13326213Swpaul}
13426213Swpaul
13526213Swpaul
13626213Swpaul
13726213Swpaul/*
13826213Swpaul * Hex to binary conversion
13926213Swpaul */
14026213Swpaulstatic void
141189087Sedhex2bin(int len, char *hexnum, char *binnum)
14226213Swpaul{
14326213Swpaul	int i;
14426213Swpaul
14526213Swpaul	for (i = 0; i < len; i++) {
14626213Swpaul		*binnum++ = 16 * hexval(hexnum[2*i]) + hexval(hexnum[2*i+1]);
14726213Swpaul	}
14826213Swpaul}
14926213Swpaul
15026213Swpaul/*
15126213Swpaul * Binary to hex conversion
15226213Swpaul */
15326213Swpaulstatic void
154189087Sedbin2hex(int len, unsigned char *binnum, char *hexnum)
15526213Swpaul{
15626213Swpaul	int i;
15726213Swpaul	unsigned val;
15826213Swpaul
15926213Swpaul	for (i = 0; i < len; i++) {
16026213Swpaul		val = binnum[i];
16126213Swpaul		hexnum[i*2] = hex[val >> 4];
16226213Swpaul		hexnum[i*2+1] = hex[val & 0xf];
16326213Swpaul	}
16426213Swpaul	hexnum[len*2] = 0;
16526213Swpaul}
16626213Swpaul
16726213Swpaulstatic char
168189087Sedhexval(char c)
16926213Swpaul{
17026213Swpaul	if (c >= '0' && c <= '9') {
17126213Swpaul		return (c - '0');
17226213Swpaul	} else if (c >= 'a' && c <= 'z') {
17326213Swpaul		return (c - 'a' + 10);
17426213Swpaul	} else if (c >= 'A' && c <= 'Z') {
17526213Swpaul		return (c - 'A' + 10);
17626213Swpaul	} else {
17726213Swpaul		return (-1);
17826213Swpaul	}
17926213Swpaul}
180