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}
|