10f8c8396SNick Sayer /* public key routines */ 2bf4f84d4SMark Murray /* $FreeBSD$ */ 30f8c8396SNick Sayer /* functions: 40f8c8396SNick Sayer genkeys(char *public, char *secret) 50f8c8396SNick Sayer common_key(char *secret, char *public, desData *deskey) 60f8c8396SNick Sayer pk_encode(char *in, *out, DesData *deskey); 70f8c8396SNick Sayer pk_decode(char *in, *out, DesData *deskey); 80f8c8396SNick Sayer where 90f8c8396SNick Sayer char public[HEXKEYBYTES + 1]; 100f8c8396SNick Sayer char secret[HEXKEYBYTES + 1]; 110f8c8396SNick Sayer */ 120f8c8396SNick Sayer 130f8c8396SNick Sayer #include <sys/time.h> 14bf4f84d4SMark Murray #include <openssl/des.h> 1521f083c0SMark Murray #include <fcntl.h> 1621f083c0SMark Murray #include <stdio.h> 1721f083c0SMark Murray #include <string.h> 180f8c8396SNick Sayer #include "mp.h" 190f8c8396SNick Sayer #include "pk.h" 2021f083c0SMark Murray #if defined(SOLARIS2) || defined(LINUX) || defined(__FreeBSD__) 210f8c8396SNick Sayer #include <stdlib.h> 220f8c8396SNick Sayer #endif 230f8c8396SNick Sayer 2421f083c0SMark Murray static void adjust(char keyout[HEXKEYBYTES+1], char *keyin); 2521f083c0SMark Murray 260f8c8396SNick Sayer /* 270f8c8396SNick Sayer * Choose top 128 bits of the common key to use as our idea key. 280f8c8396SNick Sayer */ 2921f083c0SMark Murray static void 3021f083c0SMark Murray extractideakey(MINT *ck, IdeaData *ideakey) 310f8c8396SNick Sayer { 320f8c8396SNick Sayer MINT *a; 330f8c8396SNick Sayer MINT *z; 340f8c8396SNick Sayer short r; 350f8c8396SNick Sayer int i; 360f8c8396SNick Sayer short base = (1 << 8); 370f8c8396SNick Sayer char *k; 380f8c8396SNick Sayer 390f8c8396SNick Sayer z = itom(0); 400f8c8396SNick Sayer a = itom(0); 410f8c8396SNick Sayer madd(ck, z, a); 420f8c8396SNick Sayer for (i = 0; i < ((KEYSIZE - 128) / 8); i++) { 430f8c8396SNick Sayer sdiv(a, base, a, &r); 440f8c8396SNick Sayer } 450f8c8396SNick Sayer k = (char *)ideakey; 460f8c8396SNick Sayer for (i = 0; i < 16; i++) { 470f8c8396SNick Sayer sdiv(a, base, a, &r); 480f8c8396SNick Sayer *k++ = r; 490f8c8396SNick Sayer } 500f8c8396SNick Sayer mfree(z); 510f8c8396SNick Sayer mfree(a); 520f8c8396SNick Sayer } 530f8c8396SNick Sayer 540f8c8396SNick Sayer /* 550f8c8396SNick Sayer * Choose middle 64 bits of the common key to use as our des key, possibly 560f8c8396SNick Sayer * overwriting the lower order bits by setting parity. 570f8c8396SNick Sayer */ 5821f083c0SMark Murray static void 5921f083c0SMark Murray extractdeskey(MINT *ck, DesData *deskey) 600f8c8396SNick Sayer { 610f8c8396SNick Sayer MINT *a; 620f8c8396SNick Sayer MINT *z; 630f8c8396SNick Sayer short r; 640f8c8396SNick Sayer int i; 650f8c8396SNick Sayer short base = (1 << 8); 660f8c8396SNick Sayer char *k; 670f8c8396SNick Sayer 680f8c8396SNick Sayer z = itom(0); 690f8c8396SNick Sayer a = itom(0); 700f8c8396SNick Sayer madd(ck, z, a); 710f8c8396SNick Sayer for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) { 720f8c8396SNick Sayer sdiv(a, base, a, &r); 730f8c8396SNick Sayer } 740f8c8396SNick Sayer k = (char *)deskey; 750f8c8396SNick Sayer for (i = 0; i < 8; i++) { 760f8c8396SNick Sayer sdiv(a, base, a, &r); 770f8c8396SNick Sayer *k++ = r; 780f8c8396SNick Sayer } 790f8c8396SNick Sayer mfree(z); 800f8c8396SNick Sayer mfree(a); 810f8c8396SNick Sayer } 820f8c8396SNick Sayer 830f8c8396SNick Sayer /* 840f8c8396SNick Sayer * get common key from my secret key and his public key 850f8c8396SNick Sayer */ 8621f083c0SMark Murray void 8721f083c0SMark Murray common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey) 880f8c8396SNick Sayer { 890f8c8396SNick Sayer MINT *public; 900f8c8396SNick Sayer MINT *secret; 910f8c8396SNick Sayer MINT *common; 920f8c8396SNick Sayer MINT *modulus = xtom(HEXMODULUS); 930f8c8396SNick Sayer 940f8c8396SNick Sayer public = xtom(xpublic); 950f8c8396SNick Sayer secret = xtom(xsecret); 960f8c8396SNick Sayer common = itom(0); 970f8c8396SNick Sayer pow(public, secret, modulus, common); 980f8c8396SNick Sayer extractdeskey(common, deskey); 990f8c8396SNick Sayer extractideakey(common, ideakey); 1000f8c8396SNick Sayer #if DES_OSTHOLM 1010f8c8396SNick Sayer des_fixup_key_parity(deskey); 1020f8c8396SNick Sayer #else 1030f8c8396SNick Sayer des_set_odd_parity(deskey); 1040f8c8396SNick Sayer #endif 1050f8c8396SNick Sayer mfree(common); 1060f8c8396SNick Sayer mfree(secret); 1070f8c8396SNick Sayer mfree(public); 1080f8c8396SNick Sayer mfree(modulus); 1090f8c8396SNick Sayer } 1100f8c8396SNick Sayer 1110f8c8396SNick Sayer /* 1120f8c8396SNick Sayer * Generate a seed 1130f8c8396SNick Sayer */ 11421f083c0SMark Murray void 11521f083c0SMark Murray getseed(char *seed, int seedsize) 1160f8c8396SNick Sayer { 117d48d5be0SPeter Wemm int i; 118d48d5be0SPeter Wemm 1198183ac8fSNick Sayer srandomdev(); 1208183ac8fSNick Sayer for (i = 0; i < seedsize; i++) { 1218183ac8fSNick Sayer seed[i] = random() & 0xff; 1228183ac8fSNick Sayer } 1230f8c8396SNick Sayer } 1240f8c8396SNick Sayer 1250f8c8396SNick Sayer /* 1260f8c8396SNick Sayer * Generate a random public/secret key pair 1270f8c8396SNick Sayer */ 12821f083c0SMark Murray void 12921f083c0SMark Murray genkeys(char *public, char *secret) 1300f8c8396SNick Sayer { 1310f8c8396SNick Sayer int i; 1320f8c8396SNick Sayer 1330f8c8396SNick Sayer # define BASEBITS (8*sizeof(short) - 1) 1340f8c8396SNick Sayer # define BASE (1 << BASEBITS) 1350f8c8396SNick Sayer 1360f8c8396SNick Sayer MINT *pk = itom(0); 1370f8c8396SNick Sayer MINT *sk = itom(0); 1380f8c8396SNick Sayer MINT *tmp; 1390f8c8396SNick Sayer MINT *base = itom(BASE); 1400f8c8396SNick Sayer MINT *root = itom(PROOT); 1410f8c8396SNick Sayer MINT *modulus = xtom(HEXMODULUS); 1420f8c8396SNick Sayer short r; 1430f8c8396SNick Sayer unsigned short seed[KEYSIZE/BASEBITS + 1]; 1440f8c8396SNick Sayer char *xkey; 1450f8c8396SNick Sayer 1460f8c8396SNick Sayer getseed((char *)seed, sizeof(seed)); 1470f8c8396SNick Sayer for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) { 1480f8c8396SNick Sayer r = seed[i] % BASE; 1490f8c8396SNick Sayer tmp = itom(r); 1500f8c8396SNick Sayer mult(sk, base, sk); 1510f8c8396SNick Sayer madd(sk, tmp, sk); 1520f8c8396SNick Sayer mfree(tmp); 1530f8c8396SNick Sayer } 1540f8c8396SNick Sayer tmp = itom(0); 1550f8c8396SNick Sayer mdiv(sk, modulus, tmp, sk); 1560f8c8396SNick Sayer mfree(tmp); 1570f8c8396SNick Sayer pow(root, sk, modulus, pk); 1580f8c8396SNick Sayer xkey = mtox(sk); 1590f8c8396SNick Sayer adjust(secret, xkey); 1600f8c8396SNick Sayer xkey = mtox(pk); 1610f8c8396SNick Sayer adjust(public, xkey); 1620f8c8396SNick Sayer mfree(sk); 1630f8c8396SNick Sayer mfree(base); 1640f8c8396SNick Sayer mfree(pk); 1650f8c8396SNick Sayer mfree(root); 1660f8c8396SNick Sayer mfree(modulus); 1670f8c8396SNick Sayer } 1680f8c8396SNick Sayer 1690f8c8396SNick Sayer /* 1700f8c8396SNick Sayer * Adjust the input key so that it is 0-filled on the left 1710f8c8396SNick Sayer */ 17221f083c0SMark Murray static void 17321f083c0SMark Murray adjust(char keyout[HEXKEYBYTES+1], char *keyin) 1740f8c8396SNick Sayer { 1750f8c8396SNick Sayer char *p; 1760f8c8396SNick Sayer char *s; 1770f8c8396SNick Sayer 1780f8c8396SNick Sayer for (p = keyin; *p; p++) 1790f8c8396SNick Sayer ; 1800f8c8396SNick Sayer for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) { 1810f8c8396SNick Sayer *s = *p; 1820f8c8396SNick Sayer } 1830f8c8396SNick Sayer while (s >= keyout) { 1840f8c8396SNick Sayer *s-- = '0'; 1850f8c8396SNick Sayer } 1860f8c8396SNick Sayer } 1870f8c8396SNick Sayer 1880f8c8396SNick Sayer static char hextab[17] = "0123456789ABCDEF"; 1890f8c8396SNick Sayer 1900f8c8396SNick Sayer /* given a DES key, cbc encrypt and translate input to terminated hex */ 19121f083c0SMark Murray void 19221f083c0SMark Murray pk_encode(char *in, char *out, DesData *key) 1930f8c8396SNick Sayer { 1940f8c8396SNick Sayer char buf[256]; 1950f8c8396SNick Sayer DesData i; 1960f8c8396SNick Sayer des_key_schedule k; 1970f8c8396SNick Sayer int l,op,deslen; 1980f8c8396SNick Sayer 1990f8c8396SNick Sayer memset(&i,0,sizeof(i)); 2000f8c8396SNick Sayer memset(buf,0,sizeof(buf)); 2010f8c8396SNick Sayer deslen = ((strlen(in) + 7)/8)*8; 2020f8c8396SNick Sayer des_key_sched(key, k); 203d48d5be0SPeter Wemm des_cbc_encrypt(in,buf,deslen, k,&i,DES_ENCRYPT); 2040f8c8396SNick Sayer for (l=0,op=0;l<deslen;l++) { 2050f8c8396SNick Sayer out[op++] = hextab[(buf[l] & 0xf0) >> 4]; 2060f8c8396SNick Sayer out[op++] = hextab[(buf[l] & 0x0f)]; 2070f8c8396SNick Sayer } 2080f8c8396SNick Sayer out[op] = '\0'; 2090f8c8396SNick Sayer } 2100f8c8396SNick Sayer 2110f8c8396SNick Sayer /* given a DES key, translate input from hex and decrypt */ 21221f083c0SMark Murray void 21321f083c0SMark Murray pk_decode(char *in, char *out, DesData *key) 2140f8c8396SNick Sayer { 2150f8c8396SNick Sayer char buf[256]; 2160f8c8396SNick Sayer DesData i; 2170f8c8396SNick Sayer des_key_schedule k; 2180f8c8396SNick Sayer int l,n1,n2,op; 2190f8c8396SNick Sayer 2200f8c8396SNick Sayer memset(&i,0,sizeof(i)); 2210f8c8396SNick Sayer memset(buf,0,sizeof(buf)); 2220f8c8396SNick Sayer for (l=0,op=0;l<strlen(in)/2;l++,op+=2) { 2230f8c8396SNick Sayer if(in[op] == '0' && in[op+1] == '0') { 2240f8c8396SNick Sayer buf[l] = '\0'; 2250f8c8396SNick Sayer break; 2260f8c8396SNick Sayer } 2270f8c8396SNick Sayer if (in[op] > '9') 2280f8c8396SNick Sayer n1 = in[op] - 'A' + 10; 2290f8c8396SNick Sayer else 2300f8c8396SNick Sayer n1 = in[op] - '0'; 2310f8c8396SNick Sayer if (in[op+1] > '9') 2320f8c8396SNick Sayer n2 = in[op+1] - 'A' + 10; 2330f8c8396SNick Sayer else 2340f8c8396SNick Sayer n2 = in[op+1] - '0'; 2350f8c8396SNick Sayer buf[l] = n1*16 +n2; 2360f8c8396SNick Sayer } 2370f8c8396SNick Sayer des_key_sched(key, k); 238d48d5be0SPeter Wemm des_cbc_encrypt(buf,out,strlen(in)/2, k,&i,DES_DECRYPT); 2390f8c8396SNick Sayer out[strlen(in)/2] = '\0'; 2400f8c8396SNick Sayer } 241