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