Secure RPC implementation
[kopensolaris-gnu/glibc.git] / sunrpc / xcrypt.c
1 /*
2  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3  * unrestricted use provided that this legend is included on all tape
4  * media and as a part of the software program in whole or part.  Users
5  * may copy or modify Sun RPC without charge, but are not authorized
6  * to license or distribute it to anyone else except as part of a product or
7  * program developed by the user.
8  * 
9  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12  * 
13  * Sun RPC is provided with no support and without any obligation on the
14  * part of Sun Microsystems, Inc. to assist in its use, correction,
15  * modification or enhancement.
16  * 
17  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19  * OR ANY PART THEREOF.
20  * 
21  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22  * or profits or other special, indirect and consequential damages, even if
23  * Sun has been advised of the possibility of such damages.
24  * 
25  * Sun Microsystems, Inc.
26  * 2550 Garcia Avenue
27  * Mountain View, California  94043
28  */
29
30 /*
31  * Copyright (c) 1986-1991 by Sun Microsystems Inc.
32  */
33
34 #ident  "@(#)xcrypt.c   1.11    94/08/23 SMI"
35
36 #if !defined(lint) && defined(SCCSIDS)
37 static char sccsid[] = "@(#)xcrypt.c 1.3 89/03/24 Copyr 1986 Sun Micro";
38 #endif
39
40 /*
41  * xcrypt.c: Hex encryption/decryption and utility routines
42  */
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <sys/types.h>
48 #include <rpc/des_crypt.h>
49
50 static char hex[16] =
51 {
52   '0', '1', '2', '3', '4', '5', '6', '7',
53   '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
54 };
55
56 static char hexval (char);
57 static void hex2bin (int, char *, char *);
58 static void bin2hex (int, unsigned char *, char *);
59 void passwd2des (char *pw, char *key);
60
61 /*
62  * Encrypt a secret key given passwd
63  * The secret key is passed and returned in hex notation.
64  * Its length must be a multiple of 16 hex digits (64 bits).
65  */
66 int
67 xencrypt (char *secret, char *passwd)
68 {
69   char key[8];
70   char ivec[8];
71   char *buf;
72   int err;
73   int len;
74
75   len = strlen (secret) / 2;
76   buf = malloc ((unsigned) len);
77   hex2bin (len, secret, buf);
78   passwd2des (passwd, key);
79   memset (ivec, 0, 8);
80
81   err = cbc_crypt (key, buf, len, DES_ENCRYPT | DES_HW, ivec);
82   if (DES_FAILED (err))
83     {
84       free (buf);
85       return 0;
86     }
87   bin2hex (len, (unsigned char *) buf, secret);
88   free (buf);
89   return 1;
90 }
91
92 /*
93  * Decrypt secret key using passwd
94  * The secret key is passed and returned in hex notation.
95  * Once again, the length is a multiple of 16 hex digits
96  */
97 int
98 xdecrypt (char *secret, char *passwd)
99 {
100   char key[8];
101   char ivec[8];
102   char *buf;
103   int err;
104   int len;
105
106   len = strlen (secret) / 2;
107   buf = malloc ((unsigned) len);
108
109   hex2bin (len, secret, buf);
110   passwd2des (passwd, key);
111   memset (ivec, 0, 8);
112
113   err = cbc_crypt (key, buf, len, DES_DECRYPT | DES_HW, ivec);
114   if (DES_FAILED (err))
115     {
116       free (buf);
117       return 0;
118     }
119   bin2hex (len, (unsigned char *) buf, secret);
120   free (buf);
121   return 1;
122 }
123
124 /*
125  * Turn password into DES key
126  */
127 void
128 passwd2des (char *pw, char *key)
129 {
130   int i;
131
132   memset (key, 0, 8);
133   for (i = 0; *pw; i = (i + 1) % 8)
134     key[i] ^= *pw++ << 1;
135
136   des_setparity (key);
137 }
138
139 /*
140  * Hex to binary conversion
141  */
142 static void
143 hex2bin (int len, char *hexnum, char *binnum)
144 {
145   int i;
146
147   for (i = 0; i < len; i++)
148     *binnum++ = 16 * hexval (hexnum[2 * i]) + hexval (hexnum[2 * i + 1]);
149 }
150
151 /*
152  * Binary to hex conversion
153  */
154 static void
155 bin2hex (int len, unsigned char *binnum, char *hexnum)
156 {
157   int i;
158   unsigned val;
159
160   for (i = 0; i < len; i++)
161     {
162       val = binnum[i];
163       hexnum[i * 2] = hex[val >> 4];
164       hexnum[i * 2 + 1] = hex[val & 0xf];
165     }
166   hexnum[len * 2] = 0;
167 }
168
169 static char
170 hexval (char c)
171 {
172   if (c >= '0' && c <= '9')
173     return (c - '0');
174   else if (c >= 'a' && c <= 'z')
175     return (c - 'a' + 10);
176   else if (c >= 'A' && c <= 'Z')
177     return (c - 'A' + 10);
178   else
179     return -1;
180 }