Deleted Added
full compact
pk.c (76711) pk.c (81965)
1/* public key routines */
1/* public key routines */
2/* $FreeBSD: head/contrib/telnet/libtelnet/pk.c 76711 2001-05-17 03:13:00Z peter $ */
2/* $FreeBSD: head/contrib/telnet/libtelnet/pk.c 81965 2001-08-20 12:28:40Z markm $ */
3/* functions:
4 genkeys(char *public, char *secret)
5 common_key(char *secret, char *public, desData *deskey)
6 pk_encode(char *in, *out, DesData *deskey);
7 pk_decode(char *in, *out, DesData *deskey);
8 where
9 char public[HEXKEYBYTES + 1];
10 char secret[HEXKEYBYTES + 1];
11 */
12
3/* functions:
4 genkeys(char *public, char *secret)
5 common_key(char *secret, char *public, desData *deskey)
6 pk_encode(char *in, *out, DesData *deskey);
7 pk_decode(char *in, *out, DesData *deskey);
8 where
9 char public[HEXKEYBYTES + 1];
10 char secret[HEXKEYBYTES + 1];
11 */
12
13#include <stdio.h>
14#include <sys/time.h>
13#include <sys/time.h>
15#include <string.h>
16#include <fcntl.h>
17#include <openssl/des.h>
14#include <openssl/des.h>
15#include <fcntl.h>
16#include <stdio.h>
17#include <string.h>
18#include "mp.h"
19#include "pk.h"
18#include "mp.h"
19#include "pk.h"
20#if defined(SOLARIS2) || defined(LINUX)
20#if defined(SOLARIS2) || defined(LINUX) || defined(__FreeBSD__)
21#include <stdlib.h>
22#endif
23
21#include <stdlib.h>
22#endif
23
24static void adjust(char keyout[HEXKEYBYTES+1], char *keyin);
25
24/*
25 * Choose top 128 bits of the common key to use as our idea key.
26 */
26/*
27 * Choose top 128 bits of the common key to use as our idea key.
28 */
27static
28extractideakey(ck, ideakey)
29 MINT *ck;
30 IdeaData *ideakey;
29static void
30extractideakey(MINT *ck, IdeaData *ideakey)
31{
32 MINT *a;
33 MINT *z;
34 short r;
35 int i;
36 short base = (1 << 8);
37 char *k;
38
39 z = itom(0);
40 a = itom(0);
41 madd(ck, z, a);
42 for (i = 0; i < ((KEYSIZE - 128) / 8); i++) {
43 sdiv(a, base, a, &r);
44 }
45 k = (char *)ideakey;
46 for (i = 0; i < 16; i++) {
47 sdiv(a, base, a, &r);
48 *k++ = r;
49 }
50 mfree(z);
51 mfree(a);
52}
53
54/*
55 * Choose middle 64 bits of the common key to use as our des key, possibly
56 * overwriting the lower order bits by setting parity.
57 */
31{
32 MINT *a;
33 MINT *z;
34 short r;
35 int i;
36 short base = (1 << 8);
37 char *k;
38
39 z = itom(0);
40 a = itom(0);
41 madd(ck, z, a);
42 for (i = 0; i < ((KEYSIZE - 128) / 8); i++) {
43 sdiv(a, base, a, &r);
44 }
45 k = (char *)ideakey;
46 for (i = 0; i < 16; i++) {
47 sdiv(a, base, a, &r);
48 *k++ = r;
49 }
50 mfree(z);
51 mfree(a);
52}
53
54/*
55 * Choose middle 64 bits of the common key to use as our des key, possibly
56 * overwriting the lower order bits by setting parity.
57 */
58static
59extractdeskey(ck, deskey)
60 MINT *ck;
61 DesData *deskey;
58static void
59extractdeskey(MINT *ck, DesData *deskey)
62{
63 MINT *a;
64 MINT *z;
65 short r;
66 int i;
67 short base = (1 << 8);
68 char *k;
69
70 z = itom(0);
71 a = itom(0);
72 madd(ck, z, a);
73 for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) {
74 sdiv(a, base, a, &r);
75 }
76 k = (char *)deskey;
77 for (i = 0; i < 8; i++) {
78 sdiv(a, base, a, &r);
79 *k++ = r;
80 }
81 mfree(z);
82 mfree(a);
83}
84
85/*
86 * get common key from my secret key and his public key
87 */
60{
61 MINT *a;
62 MINT *z;
63 short r;
64 int i;
65 short base = (1 << 8);
66 char *k;
67
68 z = itom(0);
69 a = itom(0);
70 madd(ck, z, a);
71 for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) {
72 sdiv(a, base, a, &r);
73 }
74 k = (char *)deskey;
75 for (i = 0; i < 8; i++) {
76 sdiv(a, base, a, &r);
77 *k++ = r;
78 }
79 mfree(z);
80 mfree(a);
81}
82
83/*
84 * get common key from my secret key and his public key
85 */
88void common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey)
86void
87common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey)
89{
90 MINT *public;
91 MINT *secret;
92 MINT *common;
93 MINT *modulus = xtom(HEXMODULUS);
94
95 public = xtom(xpublic);
96 secret = xtom(xsecret);
97 common = itom(0);
98 pow(public, secret, modulus, common);
99 extractdeskey(common, deskey);
100 extractideakey(common, ideakey);
101#if DES_OSTHOLM
102 des_fixup_key_parity(deskey);
103#else
104 des_set_odd_parity(deskey);
105#endif
106 mfree(common);
107 mfree(secret);
108 mfree(public);
109 mfree(modulus);
110}
111
88{
89 MINT *public;
90 MINT *secret;
91 MINT *common;
92 MINT *modulus = xtom(HEXMODULUS);
93
94 public = xtom(xpublic);
95 secret = xtom(xsecret);
96 common = itom(0);
97 pow(public, secret, modulus, common);
98 extractdeskey(common, deskey);
99 extractideakey(common, ideakey);
100#if DES_OSTHOLM
101 des_fixup_key_parity(deskey);
102#else
103 des_set_odd_parity(deskey);
104#endif
105 mfree(common);
106 mfree(secret);
107 mfree(public);
108 mfree(modulus);
109}
110
112
113/*
114 * Generate a seed
115 */
111/*
112 * Generate a seed
113 */
116void getseed(seed, seedsize)
117 char *seed;
118 int seedsize;
114void
115getseed(char *seed, int seedsize)
119{
116{
120#if 0
121 int i,f;
122 int rseed;
123 struct timeval tv;
124 long devrand;
125
126 (void)gettimeofday(&tv, (struct timezone *)NULL);
127 rseed = tv.tv_sec + tv.tv_usec;
128/* XXX What the hell is this?! */
129 for (i = 0; i < 8; i++) {
130 rseed ^= (rseed << 8);
131 }
132
133 f=open("/dev/random",O_NONBLOCK|O_RDONLY);
134 if (f>=0)
135 {
136 read(f,&devrand,sizeof(devrand));
137 close(f);
138 }
139 srand48((long)rseed^devrand);
140
141 for (i = 0; i < seedsize; i++) {
142 seed[i] = (lrand48() & 0xff);
143 }
144#else
145 int i;
146
147 srandomdev();
148 for (i = 0; i < seedsize; i++) {
149 seed[i] = random() & 0xff;
150 }
117 int i;
118
119 srandomdev();
120 for (i = 0; i < seedsize; i++) {
121 seed[i] = random() & 0xff;
122 }
151#endif
152}
153
123}
124
154
155/*
156 * Generate a random public/secret key pair
157 */
125/*
126 * Generate a random public/secret key pair
127 */
158void genkeys(public, secret)
159 char *public;
160 char *secret;
128void
129genkeys(char *public, char *secret)
161{
162 int i;
163
164# define BASEBITS (8*sizeof(short) - 1)
165# define BASE (1 << BASEBITS)
166
167 MINT *pk = itom(0);
168 MINT *sk = itom(0);
169 MINT *tmp;
170 MINT *base = itom(BASE);
171 MINT *root = itom(PROOT);
172 MINT *modulus = xtom(HEXMODULUS);
173 short r;
174 unsigned short seed[KEYSIZE/BASEBITS + 1];
175 char *xkey;
176
177 getseed((char *)seed, sizeof(seed));
178 for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) {
179 r = seed[i] % BASE;
180 tmp = itom(r);
181 mult(sk, base, sk);
182 madd(sk, tmp, sk);
183 mfree(tmp);
184 }
185 tmp = itom(0);
186 mdiv(sk, modulus, tmp, sk);
187 mfree(tmp);
188 pow(root, sk, modulus, pk);
189 xkey = mtox(sk);
190 adjust(secret, xkey);
191 xkey = mtox(pk);
192 adjust(public, xkey);
193 mfree(sk);
194 mfree(base);
195 mfree(pk);
196 mfree(root);
197 mfree(modulus);
198}
199
200/*
201 * Adjust the input key so that it is 0-filled on the left
202 */
130{
131 int i;
132
133# define BASEBITS (8*sizeof(short) - 1)
134# define BASE (1 << BASEBITS)
135
136 MINT *pk = itom(0);
137 MINT *sk = itom(0);
138 MINT *tmp;
139 MINT *base = itom(BASE);
140 MINT *root = itom(PROOT);
141 MINT *modulus = xtom(HEXMODULUS);
142 short r;
143 unsigned short seed[KEYSIZE/BASEBITS + 1];
144 char *xkey;
145
146 getseed((char *)seed, sizeof(seed));
147 for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) {
148 r = seed[i] % BASE;
149 tmp = itom(r);
150 mult(sk, base, sk);
151 madd(sk, tmp, sk);
152 mfree(tmp);
153 }
154 tmp = itom(0);
155 mdiv(sk, modulus, tmp, sk);
156 mfree(tmp);
157 pow(root, sk, modulus, pk);
158 xkey = mtox(sk);
159 adjust(secret, xkey);
160 xkey = mtox(pk);
161 adjust(public, xkey);
162 mfree(sk);
163 mfree(base);
164 mfree(pk);
165 mfree(root);
166 mfree(modulus);
167}
168
169/*
170 * Adjust the input key so that it is 0-filled on the left
171 */
203adjust(keyout, keyin)
204 char keyout[HEXKEYBYTES+1];
205 char *keyin;
172static void
173adjust(char keyout[HEXKEYBYTES+1], char *keyin)
206{
207 char *p;
208 char *s;
209
210 for (p = keyin; *p; p++)
211 ;
212 for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) {
213 *s = *p;
214 }
215 while (s >= keyout) {
216 *s-- = '0';
217 }
218}
219
220static char hextab[17] = "0123456789ABCDEF";
221
222/* given a DES key, cbc encrypt and translate input to terminated hex */
174{
175 char *p;
176 char *s;
177
178 for (p = keyin; *p; p++)
179 ;
180 for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) {
181 *s = *p;
182 }
183 while (s >= keyout) {
184 *s-- = '0';
185 }
186}
187
188static char hextab[17] = "0123456789ABCDEF";
189
190/* given a DES key, cbc encrypt and translate input to terminated hex */
223void pk_encode(in, out, key)
224char *in,*out;
225DesData *key;
191void
192pk_encode(char *in, char *out, DesData *key)
226{
227 char buf[256];
228 DesData i;
229 des_key_schedule k;
230 int l,op,deslen;
231
232 memset(&i,0,sizeof(i));
233 memset(buf,0,sizeof(buf));
234 deslen = ((strlen(in) + 7)/8)*8;
235 des_key_sched(key, k);
236 des_cbc_encrypt(in,buf,deslen, k,&i,DES_ENCRYPT);
237 for (l=0,op=0;l<deslen;l++) {
238 out[op++] = hextab[(buf[l] & 0xf0) >> 4];
239 out[op++] = hextab[(buf[l] & 0x0f)];
240 }
241 out[op] = '\0';
242}
243
244/* given a DES key, translate input from hex and decrypt */
193{
194 char buf[256];
195 DesData i;
196 des_key_schedule k;
197 int l,op,deslen;
198
199 memset(&i,0,sizeof(i));
200 memset(buf,0,sizeof(buf));
201 deslen = ((strlen(in) + 7)/8)*8;
202 des_key_sched(key, k);
203 des_cbc_encrypt(in,buf,deslen, k,&i,DES_ENCRYPT);
204 for (l=0,op=0;l<deslen;l++) {
205 out[op++] = hextab[(buf[l] & 0xf0) >> 4];
206 out[op++] = hextab[(buf[l] & 0x0f)];
207 }
208 out[op] = '\0';
209}
210
211/* given a DES key, translate input from hex and decrypt */
245void pk_decode(in, out, key)
246char *in,*out;
247DesData *key;
212void
213pk_decode(char *in, char *out, DesData *key)
248{
249 char buf[256];
250 DesData i;
251 des_key_schedule k;
252 int l,n1,n2,op;
253
254 memset(&i,0,sizeof(i));
255 memset(buf,0,sizeof(buf));
256 for (l=0,op=0;l<strlen(in)/2;l++,op+=2) {
257 if(in[op] == '0' && in[op+1] == '0') {
258 buf[l] = '\0';
259 break;
260 }
261 if (in[op] > '9')
262 n1 = in[op] - 'A' + 10;
263 else
264 n1 = in[op] - '0';
265 if (in[op+1] > '9')
266 n2 = in[op+1] - 'A' + 10;
267 else
268 n2 = in[op+1] - '0';
269 buf[l] = n1*16 +n2;
270 }
271 des_key_sched(key, k);
272 des_cbc_encrypt(buf,out,strlen(in)/2, k,&i,DES_DECRYPT);
273 out[strlen(in)/2] = '\0';
274}
214{
215 char buf[256];
216 DesData i;
217 des_key_schedule k;
218 int l,n1,n2,op;
219
220 memset(&i,0,sizeof(i));
221 memset(buf,0,sizeof(buf));
222 for (l=0,op=0;l<strlen(in)/2;l++,op+=2) {
223 if(in[op] == '0' && in[op+1] == '0') {
224 buf[l] = '\0';
225 break;
226 }
227 if (in[op] > '9')
228 n1 = in[op] - 'A' + 10;
229 else
230 n1 = in[op] - '0';
231 if (in[op+1] > '9')
232 n2 = in[op+1] - 'A' + 10;
233 else
234 n2 = in[op+1] - '0';
235 buf[l] = n1*16 +n2;
236 }
237 des_key_sched(key, k);
238 des_cbc_encrypt(buf,out,strlen(in)/2, k,&i,DES_DECRYPT);
239 out[strlen(in)/2] = '\0';
240}