BTRFS: Reimplement TreeIterator, add some error checks and remove redundancies.
[haiku.git] / src / libs / libtelnet / pk.c
blobb7a0773d01ef8765688f2be69a915bcaa4a75e2f
1 /*-
2 * Copyright (c) 1991, 1993
3 * Dave Safford. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
31 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD: src/contrib/telnet/libtelnet/pk.c,v 1.10 2002/08/22 06:19:07 nsayer Exp $");
35 /* public key routines */
36 /* functions:
37 genkeys(char *public, char *secret)
38 common_key(char *secret, char *public, desData *deskey)
39 pk_encode(char *in, *out, DesData *deskey);
40 pk_decode(char *in, *out, DesData *deskey);
41 where
42 char public[HEXKEYBYTES + 1];
43 char secret[HEXKEYBYTES + 1];
46 #include <sys/time.h>
47 #include <openssl/des.h>
48 #include <fcntl.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
53 #include "mp.h"
54 #include "pk.h"
56 static void adjust(char keyout[HEXKEYBYTES+1], char *keyin);
59 * Choose top 128 bits of the common key to use as our idea key.
61 static void
62 extractideakey(MINT *ck, IdeaData *ideakey)
64 MINT *a;
65 MINT *z;
66 short r;
67 int i;
68 short base = (1 << 8);
69 char *k;
71 z = itom(0);
72 a = itom(0);
73 madd(ck, z, a);
74 for (i = 0; i < ((KEYSIZE - 128) / 8); i++) {
75 sdiv(a, base, a, &r);
77 k = (char *)ideakey;
78 for (i = 0; i < 16; i++) {
79 sdiv(a, base, a, &r);
80 *k++ = r;
82 mfree(z);
83 mfree(a);
87 * Choose middle 64 bits of the common key to use as our des key, possibly
88 * overwriting the lower order bits by setting parity.
90 static void
91 extractdeskey(MINT *ck, DesData *deskey)
93 MINT *a;
94 MINT *z;
95 short r;
96 int i;
97 short base = (1 << 8);
98 char *k;
100 z = itom(0);
101 a = itom(0);
102 madd(ck, z, a);
103 for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) {
104 sdiv(a, base, a, &r);
106 k = (char *)deskey;
107 for (i = 0; i < 8; i++) {
108 sdiv(a, base, a, &r);
109 *k++ = r;
111 mfree(z);
112 mfree(a);
116 * get common key from my secret key and his public key
118 void
119 common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey)
121 MINT *public;
122 MINT *secret;
123 MINT *common;
124 MINT *modulus = xtom(HEXMODULUS);
126 public = xtom(xpublic);
127 secret = xtom(xsecret);
128 common = itom(0);
129 pow(public, secret, modulus, common);
130 extractdeskey(common, deskey);
131 extractideakey(common, ideakey);
132 des_set_odd_parity(deskey);
133 mfree(common);
134 mfree(secret);
135 mfree(public);
136 mfree(modulus);
140 * Generate a seed
142 static void
143 getseed(char *seed, int seedsize)
145 int i;
147 srandomdev();
148 for (i = 0; i < seedsize; i++) {
149 seed[i] = random() & 0xff;
154 * Generate a random public/secret key pair
156 void
157 genkeys(char *public, char *secret)
159 size_t i;
161 # define BASEBITS (8*sizeof(short) - 1)
162 # define BASE (1 << BASEBITS)
164 MINT *pk = itom(0);
165 MINT *sk = itom(0);
166 MINT *tmp;
167 MINT *base = itom(BASE);
168 MINT *root = itom(PROOT);
169 MINT *modulus = xtom(HEXMODULUS);
170 short r;
171 unsigned short seed[KEYSIZE/BASEBITS + 1];
172 char *xkey;
174 getseed((char *)seed, sizeof(seed));
175 for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) {
176 r = seed[i] % BASE;
177 tmp = itom(r);
178 mult(sk, base, sk);
179 madd(sk, tmp, sk);
180 mfree(tmp);
182 tmp = itom(0);
183 mdiv(sk, modulus, tmp, sk);
184 mfree(tmp);
185 pow(root, sk, modulus, pk);
186 xkey = mtox(sk);
187 adjust(secret, xkey);
188 xkey = mtox(pk);
189 adjust(public, xkey);
190 mfree(sk);
191 mfree(base);
192 mfree(pk);
193 mfree(root);
194 mfree(modulus);
198 * Adjust the input key so that it is 0-filled on the left
200 static void
201 adjust(char keyout[HEXKEYBYTES+1], char *keyin)
203 char *p;
204 char *s;
206 for (p = keyin; *p; p++)
208 for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) {
209 *s = *p;
211 while (s >= keyout) {
212 *s-- = '0';
216 static char hextab[17] = "0123456789ABCDEF";
218 /* given a DES key, cbc encrypt and translate input to terminated hex */
219 void
220 pk_encode(char *in, char *out, DesData *key)
222 char buf[256];
223 DesData i;
224 des_key_schedule k;
225 int l,op,deslen;
227 memset(&i,0,sizeof(i));
228 memset(buf,0,sizeof(buf));
229 deslen = ((strlen(in) + 7)/8)*8;
230 des_key_sched(key, k);
231 des_cbc_encrypt(in,buf,deslen, k,&i,DES_ENCRYPT);
232 for (l=0,op=0;l<deslen;l++) {
233 out[op++] = hextab[(buf[l] & 0xf0) >> 4];
234 out[op++] = hextab[(buf[l] & 0x0f)];
236 out[op] = '\0';
239 /* given a DES key, translate input from hex and decrypt */
240 void
241 pk_decode(char *in, char *out, DesData *key)
243 char buf[256];
244 DesData i;
245 des_key_schedule k;
246 int n1,n2,op;
247 size_t l;
249 memset(&i,0,sizeof(i));
250 memset(buf,0,sizeof(buf));
251 for (l=0,op=0;l<strlen(in)/2;l++,op+=2) {
252 if (in[op] > '9')
253 n1 = in[op] - 'A' + 10;
254 else
255 n1 = in[op] - '0';
256 if (in[op+1] > '9')
257 n2 = in[op+1] - 'A' + 10;
258 else
259 n2 = in[op+1] - '0';
260 buf[l] = n1*16 +n2;
262 des_key_sched(key, k);
263 des_cbc_encrypt(buf,out,strlen(in)/2, k,&i,DES_DECRYPT);
264 out[strlen(in)/2] = '\0';