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