13737d6dfSNick Sayer /*- 23737d6dfSNick Sayer * Copyright (c) 1991, 1993 33737d6dfSNick Sayer * Dave Safford. All rights reserved. 43737d6dfSNick Sayer * 53737d6dfSNick Sayer * Redistribution and use in source and binary forms, with or without 63737d6dfSNick Sayer * modification, are permitted provided that the following conditions 73737d6dfSNick Sayer * are met: 83737d6dfSNick Sayer * 1. Redistributions of source code must retain the above copyright 93737d6dfSNick Sayer * notice, this list of conditions and the following disclaimer. 103737d6dfSNick Sayer * 2. Redistributions in binary form must reproduce the above copyright 113737d6dfSNick Sayer * notice, this list of conditions and the following disclaimer in the 123737d6dfSNick Sayer * documentation and/or other materials provided with the distribution. 133737d6dfSNick Sayer * 3. Neither the name of the University nor the names of its contributors 143737d6dfSNick Sayer * may be used to endorse or promote products derived from this software 153737d6dfSNick Sayer * without specific prior written permission. 163737d6dfSNick Sayer * 173737d6dfSNick Sayer * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 183737d6dfSNick Sayer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 193737d6dfSNick Sayer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 203737d6dfSNick Sayer * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 213737d6dfSNick Sayer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 223737d6dfSNick Sayer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 233737d6dfSNick Sayer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 243737d6dfSNick Sayer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 253737d6dfSNick Sayer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 263737d6dfSNick Sayer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 273737d6dfSNick Sayer * SUCH DAMAGE. 283737d6dfSNick Sayer * 293737d6dfSNick Sayer */ 303737d6dfSNick Sayer 318fa113e5SMark Murray #include <sys/cdefs.h> 328fa113e5SMark Murray 338fa113e5SMark Murray __FBSDID("$FreeBSD$"); 348fa113e5SMark Murray 350f8c8396SNick Sayer /* public key routines */ 360f8c8396SNick Sayer /* functions: 370f8c8396SNick Sayer genkeys(char *public, char *secret) 380f8c8396SNick Sayer common_key(char *secret, char *public, desData *deskey) 390f8c8396SNick Sayer pk_encode(char *in, *out, DesData *deskey); 400f8c8396SNick Sayer pk_decode(char *in, *out, DesData *deskey); 410f8c8396SNick Sayer where 420f8c8396SNick Sayer char public[HEXKEYBYTES + 1]; 430f8c8396SNick Sayer char secret[HEXKEYBYTES + 1]; 440f8c8396SNick Sayer */ 450f8c8396SNick Sayer 460f8c8396SNick Sayer #include <sys/time.h> 47bf4f84d4SMark Murray #include <openssl/des.h> 4821f083c0SMark Murray #include <fcntl.h> 4921f083c0SMark Murray #include <stdio.h> 508fa113e5SMark Murray #include <stdlib.h> 5121f083c0SMark Murray #include <string.h> 528fa113e5SMark Murray 530f8c8396SNick Sayer #include "mp.h" 540f8c8396SNick Sayer #include "pk.h" 550f8c8396SNick Sayer 5621f083c0SMark Murray static void adjust(char keyout[HEXKEYBYTES+1], char *keyin); 5721f083c0SMark Murray 580f8c8396SNick Sayer /* 590f8c8396SNick Sayer * Choose top 128 bits of the common key to use as our idea key. 600f8c8396SNick Sayer */ 6121f083c0SMark Murray static void 6221f083c0SMark Murray extractideakey(MINT *ck, IdeaData *ideakey) 630f8c8396SNick Sayer { 640f8c8396SNick Sayer MINT *a; 650f8c8396SNick Sayer MINT *z; 660f8c8396SNick Sayer short r; 670f8c8396SNick Sayer int i; 680f8c8396SNick Sayer short base = (1 << 8); 690f8c8396SNick Sayer char *k; 700f8c8396SNick Sayer 710f8c8396SNick Sayer z = itom(0); 720f8c8396SNick Sayer a = itom(0); 730f8c8396SNick Sayer madd(ck, z, a); 740f8c8396SNick Sayer for (i = 0; i < ((KEYSIZE - 128) / 8); i++) { 750f8c8396SNick Sayer sdiv(a, base, a, &r); 760f8c8396SNick Sayer } 770f8c8396SNick Sayer k = (char *)ideakey; 780f8c8396SNick Sayer for (i = 0; i < 16; i++) { 790f8c8396SNick Sayer sdiv(a, base, a, &r); 800f8c8396SNick Sayer *k++ = r; 810f8c8396SNick Sayer } 820f8c8396SNick Sayer mfree(z); 830f8c8396SNick Sayer mfree(a); 840f8c8396SNick Sayer } 850f8c8396SNick Sayer 860f8c8396SNick Sayer /* 870f8c8396SNick Sayer * Choose middle 64 bits of the common key to use as our des key, possibly 880f8c8396SNick Sayer * overwriting the lower order bits by setting parity. 890f8c8396SNick Sayer */ 9021f083c0SMark Murray static void 9121f083c0SMark Murray extractdeskey(MINT *ck, DesData *deskey) 920f8c8396SNick Sayer { 930f8c8396SNick Sayer MINT *a; 940f8c8396SNick Sayer MINT *z; 950f8c8396SNick Sayer short r; 960f8c8396SNick Sayer int i; 970f8c8396SNick Sayer short base = (1 << 8); 980f8c8396SNick Sayer char *k; 990f8c8396SNick Sayer 1000f8c8396SNick Sayer z = itom(0); 1010f8c8396SNick Sayer a = itom(0); 1020f8c8396SNick Sayer madd(ck, z, a); 1030f8c8396SNick Sayer for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) { 1040f8c8396SNick Sayer sdiv(a, base, a, &r); 1050f8c8396SNick Sayer } 1060f8c8396SNick Sayer k = (char *)deskey; 1070f8c8396SNick Sayer for (i = 0; i < 8; i++) { 1080f8c8396SNick Sayer sdiv(a, base, a, &r); 1090f8c8396SNick Sayer *k++ = r; 1100f8c8396SNick Sayer } 1110f8c8396SNick Sayer mfree(z); 1120f8c8396SNick Sayer mfree(a); 1130f8c8396SNick Sayer } 1140f8c8396SNick Sayer 1150f8c8396SNick Sayer /* 1160f8c8396SNick Sayer * get common key from my secret key and his public key 1170f8c8396SNick Sayer */ 11821f083c0SMark Murray void 11921f083c0SMark Murray common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey) 1200f8c8396SNick Sayer { 1210f8c8396SNick Sayer MINT *public; 1220f8c8396SNick Sayer MINT *secret; 1230f8c8396SNick Sayer MINT *common; 1240f8c8396SNick Sayer MINT *modulus = xtom(HEXMODULUS); 1250f8c8396SNick Sayer 1260f8c8396SNick Sayer public = xtom(xpublic); 1270f8c8396SNick Sayer secret = xtom(xsecret); 1280f8c8396SNick Sayer common = itom(0); 1290f8c8396SNick Sayer pow(public, secret, modulus, common); 1300f8c8396SNick Sayer extractdeskey(common, deskey); 1310f8c8396SNick Sayer extractideakey(common, ideakey); 1320f8c8396SNick Sayer des_set_odd_parity(deskey); 1330f8c8396SNick Sayer mfree(common); 1340f8c8396SNick Sayer mfree(secret); 1350f8c8396SNick Sayer mfree(public); 1360f8c8396SNick Sayer mfree(modulus); 1370f8c8396SNick Sayer } 1380f8c8396SNick Sayer 1390f8c8396SNick Sayer /* 1400f8c8396SNick Sayer * Generate a seed 1410f8c8396SNick Sayer */ 1428fa113e5SMark Murray static void 14321f083c0SMark Murray getseed(char *seed, int seedsize) 1440f8c8396SNick Sayer { 145d48d5be0SPeter Wemm int i; 146d48d5be0SPeter Wemm 1478183ac8fSNick Sayer srandomdev(); 1488183ac8fSNick Sayer for (i = 0; i < seedsize; i++) { 1498183ac8fSNick Sayer seed[i] = random() & 0xff; 1508183ac8fSNick Sayer } 1510f8c8396SNick Sayer } 1520f8c8396SNick Sayer 1530f8c8396SNick Sayer /* 1540f8c8396SNick Sayer * Generate a random public/secret key pair 1550f8c8396SNick Sayer */ 15621f083c0SMark Murray void 15721f083c0SMark Murray genkeys(char *public, char *secret) 1580f8c8396SNick Sayer { 1598fa113e5SMark Murray size_t i; 1600f8c8396SNick Sayer 1610f8c8396SNick Sayer # define BASEBITS (8*sizeof(short) - 1) 1620f8c8396SNick Sayer # define BASE (1 << BASEBITS) 1630f8c8396SNick Sayer 1640f8c8396SNick Sayer MINT *pk = itom(0); 1650f8c8396SNick Sayer MINT *sk = itom(0); 1660f8c8396SNick Sayer MINT *tmp; 1670f8c8396SNick Sayer MINT *base = itom(BASE); 1680f8c8396SNick Sayer MINT *root = itom(PROOT); 1690f8c8396SNick Sayer MINT *modulus = xtom(HEXMODULUS); 1700f8c8396SNick Sayer short r; 1710f8c8396SNick Sayer unsigned short seed[KEYSIZE/BASEBITS + 1]; 1720f8c8396SNick Sayer char *xkey; 1730f8c8396SNick Sayer 1740f8c8396SNick Sayer getseed((char *)seed, sizeof(seed)); 1750f8c8396SNick Sayer for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) { 1760f8c8396SNick Sayer r = seed[i] % BASE; 1770f8c8396SNick Sayer tmp = itom(r); 1780f8c8396SNick Sayer mult(sk, base, sk); 1790f8c8396SNick Sayer madd(sk, tmp, sk); 1800f8c8396SNick Sayer mfree(tmp); 1810f8c8396SNick Sayer } 1820f8c8396SNick Sayer tmp = itom(0); 1830f8c8396SNick Sayer mdiv(sk, modulus, tmp, sk); 1840f8c8396SNick Sayer mfree(tmp); 1850f8c8396SNick Sayer pow(root, sk, modulus, pk); 1860f8c8396SNick Sayer xkey = mtox(sk); 1870f8c8396SNick Sayer adjust(secret, xkey); 1880f8c8396SNick Sayer xkey = mtox(pk); 1890f8c8396SNick Sayer adjust(public, xkey); 1900f8c8396SNick Sayer mfree(sk); 1910f8c8396SNick Sayer mfree(base); 1920f8c8396SNick Sayer mfree(pk); 1930f8c8396SNick Sayer mfree(root); 1940f8c8396SNick Sayer mfree(modulus); 1950f8c8396SNick Sayer } 1960f8c8396SNick Sayer 1970f8c8396SNick Sayer /* 1980f8c8396SNick Sayer * Adjust the input key so that it is 0-filled on the left 1990f8c8396SNick Sayer */ 20021f083c0SMark Murray static void 20121f083c0SMark Murray adjust(char keyout[HEXKEYBYTES+1], char *keyin) 2020f8c8396SNick Sayer { 2030f8c8396SNick Sayer char *p; 2040f8c8396SNick Sayer char *s; 2050f8c8396SNick Sayer 2060f8c8396SNick Sayer for (p = keyin; *p; p++) 2070f8c8396SNick Sayer ; 2080f8c8396SNick Sayer for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) { 2090f8c8396SNick Sayer *s = *p; 2100f8c8396SNick Sayer } 2110f8c8396SNick Sayer while (s >= keyout) { 2120f8c8396SNick Sayer *s-- = '0'; 2130f8c8396SNick Sayer } 2140f8c8396SNick Sayer } 2150f8c8396SNick Sayer 2160f8c8396SNick Sayer static char hextab[17] = "0123456789ABCDEF"; 2170f8c8396SNick Sayer 2180f8c8396SNick Sayer /* given a DES key, cbc encrypt and translate input to terminated hex */ 21921f083c0SMark Murray void 22021f083c0SMark Murray pk_encode(char *in, char *out, DesData *key) 2210f8c8396SNick Sayer { 2220f8c8396SNick Sayer char buf[256]; 2230f8c8396SNick Sayer DesData i; 2240f8c8396SNick Sayer des_key_schedule k; 2250f8c8396SNick Sayer int l,op,deslen; 2260f8c8396SNick Sayer 2270f8c8396SNick Sayer memset(&i,0,sizeof(i)); 2280f8c8396SNick Sayer memset(buf,0,sizeof(buf)); 2290f8c8396SNick Sayer deslen = ((strlen(in) + 7)/8)*8; 2300f8c8396SNick Sayer des_key_sched(key, k); 231d48d5be0SPeter Wemm des_cbc_encrypt(in,buf,deslen, k,&i,DES_ENCRYPT); 2320f8c8396SNick Sayer for (l=0,op=0;l<deslen;l++) { 2330f8c8396SNick Sayer out[op++] = hextab[(buf[l] & 0xf0) >> 4]; 2340f8c8396SNick Sayer out[op++] = hextab[(buf[l] & 0x0f)]; 2350f8c8396SNick Sayer } 2360f8c8396SNick Sayer out[op] = '\0'; 2370f8c8396SNick Sayer } 2380f8c8396SNick Sayer 2390f8c8396SNick Sayer /* given a DES key, translate input from hex and decrypt */ 24021f083c0SMark Murray void 24121f083c0SMark Murray pk_decode(char *in, char *out, DesData *key) 2420f8c8396SNick Sayer { 2430f8c8396SNick Sayer char buf[256]; 2440f8c8396SNick Sayer DesData i; 2450f8c8396SNick Sayer des_key_schedule k; 2468fa113e5SMark Murray int n1,n2,op; 2478fa113e5SMark Murray size_t l; 2480f8c8396SNick Sayer 2490f8c8396SNick Sayer memset(&i,0,sizeof(i)); 2500f8c8396SNick Sayer memset(buf,0,sizeof(buf)); 2510f8c8396SNick Sayer for (l=0,op=0;l<strlen(in)/2;l++,op+=2) { 2520f8c8396SNick Sayer if(in[op] == '0' && in[op+1] == '0') { 2530f8c8396SNick Sayer buf[l] = '\0'; 2540f8c8396SNick Sayer break; 2550f8c8396SNick Sayer } 2560f8c8396SNick Sayer if (in[op] > '9') 2570f8c8396SNick Sayer n1 = in[op] - 'A' + 10; 2580f8c8396SNick Sayer else 2590f8c8396SNick Sayer n1 = in[op] - '0'; 2600f8c8396SNick Sayer if (in[op+1] > '9') 2610f8c8396SNick Sayer n2 = in[op+1] - 'A' + 10; 2620f8c8396SNick Sayer else 2630f8c8396SNick Sayer n2 = in[op+1] - '0'; 2640f8c8396SNick Sayer buf[l] = n1*16 +n2; 2650f8c8396SNick Sayer } 2660f8c8396SNick Sayer des_key_sched(key, k); 267d48d5be0SPeter Wemm des_cbc_encrypt(buf,out,strlen(in)/2, k,&i,DES_DECRYPT); 2680f8c8396SNick Sayer out[strlen(in)/2] = '\0'; 2690f8c8396SNick Sayer } 270