comm: add -Wall
[unleashed.git] / usr / src / cmd / keyserv / gen_dhkeys.c
blob4996363dbcb5d612803cc84bf2e6d0c2a3de8446
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * Portions of this source code were derived from Berkeley 4.3 BSD
32 * under license from the Regents of the University of California.
35 #pragma ident "%Z%%M% %I% %E% SMI"
37 #include <stdlib.h>
38 #include <mp.h>
39 #include <rpc/key_prot.h>
40 #include <rpcsvc/nis_dhext.h>
41 #include <thread.h>
43 extern long random();
44 extern void _mp_move(MINT *, MINT *);
45 extern void des_setparity(char *);
46 static void adjust();
47 void __gen_dhkeys();
49 static MINT *MODULUS_192_0;
50 static mutex_t mod_192_0_lck = DEFAULTMUTEX;
51 static bool_t first_time = TRUE;
54 * symbol names for the entry points into the Diffie-Hellman
55 * GSS mech backend routines
57 static char dl_gen_funcname[] = "__dl_gen_dhkeys";
58 static char dl_gen_common_funcname[] = "__dl_gen_common_dhkeys";
61 * Generate a seed
63 static void
64 getseed(seed, seedsize, pass)
65 char *seed;
66 int seedsize;
67 unsigned char *pass;
69 int i;
70 int rseed;
71 struct timeval tv;
73 (void) gettimeofday(&tv, NULL);
74 rseed = tv.tv_sec + tv.tv_usec;
75 for (i = 0; i < 8; i++) {
76 rseed ^= (rseed << 8) | pass[i];
78 (void) srandom(rseed);
80 for (i = 0; i < seedsize; i++) {
81 seed[i] = (random() & 0xff) ^ pass[i % 8];
86 * Adjust the input key so that it is 0-filled on the left
88 static void
89 adjust(keyout, keyin)
90 char keyout[HEXKEYBYTES + 1];
91 char *keyin;
93 char *p;
94 char *s;
96 for (p = keyin; *p; p++)
98 for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) {
99 *s = *p;
101 while (s >= keyout) {
102 *s-- = '0';
107 * generate a Diffie-Hellman key-pair based on the given password.
108 * public and secret are buffers of size HEXKEYBYTES + 1.
110 void
111 __gen_dhkeys(public, secret, pass)
112 char *public;
113 char *secret;
114 char *pass;
116 int i;
118 #define BASEBITS (8 * sizeof (short) - 1)
119 #define BASE (1 << BASEBITS)
121 MINT *pk = mp_itom(0);
122 MINT *sk = mp_itom(0);
123 MINT *tmp;
124 MINT *base = mp_itom(BASE/2); /* BASE won't fit in a short */
125 MINT *root = mp_itom(PROOT);
126 MINT *modulus = mp_xtom(HEXMODULUS);
127 unsigned short r;
128 unsigned short seed[KEYSIZE/BASEBITS + 1];
129 char *xkey;
131 /* multiply base by 2 to get BASE */
132 tmp = mp_itom(2);
133 mp_mult(base, tmp, base);
134 mp_mfree(tmp);
136 getseed((char *)seed, (int)sizeof (seed), (uchar_t *)pass);
137 for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) {
138 r = seed[i] % ((unsigned short)BASE);
139 tmp = mp_itom(r);
140 mp_mult(sk, base, sk);
141 mp_madd(sk, tmp, sk);
142 mp_mfree(tmp);
144 tmp = mp_itom(0);
145 mp_mdiv(sk, modulus, tmp, sk);
146 mp_mfree(tmp);
147 mp_pow(root, sk, modulus, pk);
148 xkey = mp_mtox(sk);
149 (void) adjust(secret, xkey);
150 xkey = mp_mtox(pk);
151 (void) adjust(public, xkey);
152 mp_mfree(sk);
153 mp_mfree(base);
154 mp_mfree(pk);
155 mp_mfree(root);
156 mp_mfree(modulus);
161 * Generic key size Diffie-Hellman key pair generation routine. For classic
162 * AUTH_DES, just call the current routine to handle it. Else, call the
163 * one in the appro GSS mech backend.
167 __gen_dhkeys_g(char *pkey, /* out */
168 char *skey, /* out */
169 keylen_t keylen, /* in */
170 algtype_t algtype, /* in */
171 char *pass) /* in */
173 const int classic_des = keylen == 192 && algtype == 0;
175 if (! pkey || ! skey || ! pass)
176 return (0);
178 if (classic_des) {
179 __gen_dhkeys(pkey, skey, pass);
180 return (1);
181 } else {
182 int (*dlfp)(); /* func ptr to dynamic loaded lib */
184 if (dlfp = (int (*)())__nis_get_mechanism_symbol(keylen,
185 algtype,
186 dl_gen_funcname)) {
187 (*dlfp)(pkey, skey, pass); /* void */
188 return (1);
192 return (0);
197 * Choose middle 64 bits of the common key to use as our des key, possibly
198 * overwriting the lower order bits by setting parity.
200 * (copied/moved) from keyserv's setkey.c for the DH extensions.
203 __extractdeskey(ck, deskey)
204 MINT *ck;
205 des_block *deskey;
207 MINT *a;
208 short r;
209 int i;
210 short base = (1 << 8);
211 char *k;
213 a = mp_itom(0);
214 _mp_move(ck, a);
215 for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) {
216 mp_sdiv(a, base, a, &r);
218 k = deskey->c;
219 for (i = 0; i < 8; i++) {
220 mp_sdiv(a, base, a, &r);
221 *k++ = r;
223 mp_mfree(a);
224 des_setparity((char *)deskey);
225 return (0);
230 * Set the modulus for all our 192bit (algtype=0) Diffie-Hellman operations
232 static void
233 setmodulus_192_0(void)
235 (void) mutex_lock(&mod_192_0_lck);
236 if (first_time) {
237 first_time = FALSE;
238 MODULUS_192_0 = mp_xtom(HEXMODULUS);
240 (void) mutex_unlock(&mod_192_0_lck);
244 * Generic key size Diffie-Hellman common key generation routine.
245 * For classic AUTH_DES, do it inline like it's already done in several
246 * places (keyserv being one place). For new long key sizes,
247 * call the appro GSS mech backend routine.
249 * Arg 'keynum' is the size of the 'deskeys' array. It should be a 1
250 * classic AUTH_DES and a 3 for new long DH keys.
252 * Returns 1 on success and 0 on err.
255 __gen_common_dhkeys_g(char *xpublic, /* in */
256 char *xsecret, /* in */
257 keylen_t keylen, /* in */
258 algtype_t algtype, /* in */
259 des_block deskeys[], /* out */
260 keynum_t keynum) /* in */
262 const int classic_des = keylen == 192 && algtype == 0;
264 if (! xpublic || ! xsecret || ! deskeys)
265 return (0);
267 if (classic_des) {
268 MINT *common;
269 MINT *public;
270 MINT *secret;
272 setmodulus_192_0();
274 public = mp_xtom(xpublic);
275 secret = mp_xtom(xsecret);
276 common = mp_itom(0);
277 mp_pow(public, secret, MODULUS_192_0, common);
278 (void) __extractdeskey(common, &deskeys[0]);
279 return (1);
280 } else {
281 int (*dlfp)(); /* func ptr to dynamically loaded lib */
283 if (dlfp = (int (*)())__nis_get_mechanism_symbol(keylen,
284 algtype,
285 dl_gen_common_funcname)) {
286 /* function called will have void return value */
287 (*dlfp)(xpublic, xsecret, deskeys, keynum);
288 return (1);
292 return (0);