1 /*- 2 * Copyright (c) 1991, 1993 3 * Dave Safford. All rights reserved. 4 * 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. 16 * 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. 28 * 29 */ 30 31 #include <sys/cdefs.h> 32 33 __FBSDID("$FreeBSD$"); 34 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]; 44 */ 45 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> 52 53 #include "mp.h" 54 #include "pk.h" 55 56 static void adjust(char keyout[HEXKEYBYTES+1], char *keyin); 57 58 /* 59 * Choose top 128 bits of the common key to use as our idea key. 60 */ 61 static void 62 extractideakey(MINT *ck, IdeaData *ideakey) 63 { 64 MINT *a; 65 MINT *z; 66 short r; 67 int i; 68 short base = (1 << 8); 69 char *k; 70 71 z = mp_itom(0); 72 a = mp_itom(0); 73 mp_madd(ck, z, a); 74 for (i = 0; i < ((KEYSIZE - 128) / 8); i++) { 75 mp_sdiv(a, base, a, &r); 76 } 77 k = (char *)ideakey; 78 for (i = 0; i < 16; i++) { 79 mp_sdiv(a, base, a, &r); 80 *k++ = r; 81 } 82 mp_mfree(z); 83 mp_mfree(a); 84 } 85 86 /* 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. 89 */ 90 static void 91 extractdeskey(MINT *ck, DesData *deskey) 92 { 93 MINT *a; 94 MINT *z; 95 short r; 96 int i; 97 short base = (1 << 8); 98 char *k; 99 100 z = mp_itom(0); 101 a = mp_itom(0); 102 mp_madd(ck, z, a); 103 for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) { 104 mp_sdiv(a, base, a, &r); 105 } 106 k = (char *)deskey; 107 for (i = 0; i < 8; i++) { 108 mp_sdiv(a, base, a, &r); 109 *k++ = r; 110 } 111 mp_mfree(z); 112 mp_mfree(a); 113 } 114 115 /* 116 * get common key from my secret key and his public key 117 */ 118 void 119 common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey) 120 { 121 MINT *public; 122 MINT *secret; 123 MINT *common; 124 MINT *modulus = mp_xtom(HEXMODULUS); 125 126 public = mp_xtom(xpublic); 127 secret = mp_xtom(xsecret); 128 common = mp_itom(0); 129 mp_pow(public, secret, modulus, common); 130 extractdeskey(common, deskey); 131 extractideakey(common, ideakey); 132 DES_set_odd_parity(deskey); 133 mp_mfree(common); 134 mp_mfree(secret); 135 mp_mfree(public); 136 mp_mfree(modulus); 137 } 138 139 /* 140 * Generate a seed 141 */ 142 static void 143 getseed(char *seed, int seedsize) 144 { 145 arc4random_buf(seed, seedsize); 146 } 147 148 /* 149 * Generate a random public/secret key pair 150 */ 151 void 152 genkeys(char *public, char *secret) 153 { 154 size_t i; 155 156 # define BASEBITS (8*sizeof(short) - 1) 157 # define BASE (1 << BASEBITS) 158 159 MINT *pk = mp_itom(0); 160 MINT *sk = mp_itom(0); 161 MINT *tmp; 162 MINT *base = mp_itom((short)BASE); 163 MINT *root = mp_itom(PROOT); 164 MINT *modulus = mp_xtom(HEXMODULUS); 165 short r; 166 unsigned short seed[KEYSIZE/BASEBITS + 1]; 167 char *xkey; 168 169 getseed((char *)seed, sizeof(seed)); 170 for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) { 171 r = seed[i] % BASE; 172 tmp = mp_itom(r); 173 mp_mult(sk, base, sk); 174 mp_madd(sk, tmp, sk); 175 mp_mfree(tmp); 176 } 177 tmp = mp_itom(0); 178 mp_mdiv(sk, modulus, tmp, sk); 179 mp_mfree(tmp); 180 mp_pow(root, sk, modulus, pk); 181 xkey = mp_mtox(sk); 182 adjust(secret, xkey); 183 xkey = mp_mtox(pk); 184 adjust(public, xkey); 185 mp_mfree(sk); 186 mp_mfree(base); 187 mp_mfree(pk); 188 mp_mfree(root); 189 mp_mfree(modulus); 190 } 191 192 /* 193 * Adjust the input key so that it is 0-filled on the left 194 */ 195 static void 196 adjust(char keyout[HEXKEYBYTES+1], char *keyin) 197 { 198 char *p; 199 char *s; 200 201 for (p = keyin; *p; p++) 202 ; 203 for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) { 204 *s = *p; 205 } 206 while (s >= keyout) { 207 *s-- = '0'; 208 } 209 } 210 211 static char hextab[17] = "0123456789ABCDEF"; 212 213 /* given a DES key, cbc encrypt and translate input to terminated hex */ 214 void 215 pk_encode(char *in, char *out, DesData *key) 216 { 217 char buf[256]; 218 DesData i; 219 DES_key_schedule k; 220 int l,op,deslen; 221 222 memset(&i,0,sizeof(i)); 223 memset(buf,0,sizeof(buf)); 224 deslen = ((strlen(in) + 7)/8)*8; 225 DES_key_sched(key, &k); 226 DES_cbc_encrypt(in, buf, deslen, &k, &i, DES_ENCRYPT); 227 for (l=0,op=0;l<deslen;l++) { 228 out[op++] = hextab[(buf[l] & 0xf0) >> 4]; 229 out[op++] = hextab[(buf[l] & 0x0f)]; 230 } 231 out[op] = '\0'; 232 } 233 234 /* given a DES key, translate input from hex and decrypt */ 235 void 236 pk_decode(char *in, char *out, DesData *key) 237 { 238 char buf[256]; 239 DesData i; 240 DES_key_schedule k; 241 int n1,n2,op; 242 size_t l; 243 244 memset(&i,0,sizeof(i)); 245 memset(buf,0,sizeof(buf)); 246 for (l=0,op=0;l<strlen(in)/2;l++,op+=2) { 247 if (in[op] > '9') 248 n1 = in[op] - 'A' + 10; 249 else 250 n1 = in[op] - '0'; 251 if (in[op+1] > '9') 252 n2 = in[op+1] - 'A' + 10; 253 else 254 n2 = in[op+1] - '0'; 255 buf[l] = n1*16 +n2; 256 } 257 DES_key_sched(key, &k); 258 DES_cbc_encrypt(buf, out, strlen(in) / 2, &k, &i, DES_DECRYPT); 259 out[strlen(in)/2] = '\0'; 260 } 261