185690Snsayer/*- 285690Snsayer * Copyright (c) 1991, 1993 385690Snsayer * Dave Safford. All rights reserved. 485690Snsayer * 585690Snsayer * Redistribution and use in source and binary forms, with or without 685690Snsayer * modification, are permitted provided that the following conditions 785690Snsayer * are met: 885690Snsayer * 1. Redistributions of source code must retain the above copyright 985690Snsayer * notice, this list of conditions and the following disclaimer. 1085690Snsayer * 2. Redistributions in binary form must reproduce the above copyright 1185690Snsayer * notice, this list of conditions and the following disclaimer in the 1285690Snsayer * documentation and/or other materials provided with the distribution. 1385690Snsayer * 3. Neither the name of the University nor the names of its contributors 1485690Snsayer * may be used to endorse or promote products derived from this software 1585690Snsayer * without specific prior written permission. 1685690Snsayer * 1785690Snsayer * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1885690Snsayer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1985690Snsayer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2085690Snsayer * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2185690Snsayer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2285690Snsayer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2385690Snsayer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2485690Snsayer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2585690Snsayer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2685690Snsayer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2785690Snsayer * SUCH DAMAGE. 2885690Snsayer * 2985690Snsayer */ 3085690Snsayer 3187139Smarkm#include <sys/cdefs.h> 3287139Smarkm 3387139Smarkm__FBSDID("$FreeBSD$"); 3487139Smarkm 3549887Snsayer/* public key routines */ 3649887Snsayer/* functions: 3749887Snsayer genkeys(char *public, char *secret) 3849887Snsayer common_key(char *secret, char *public, desData *deskey) 3949887Snsayer pk_encode(char *in, *out, DesData *deskey); 4049887Snsayer pk_decode(char *in, *out, DesData *deskey); 4149887Snsayer where 4249887Snsayer char public[HEXKEYBYTES + 1]; 4349887Snsayer char secret[HEXKEYBYTES + 1]; 4449887Snsayer */ 4549887Snsayer 4681965Smarkm#include <sys/time.h> 4781965Smarkm#include <openssl/des.h> 4881965Smarkm#include <fcntl.h> 4949887Snsayer#include <stdio.h> 5087139Smarkm#include <stdlib.h> 5149887Snsayer#include <string.h> 5287139Smarkm 5349887Snsayer#include "mp.h" 5449887Snsayer#include "pk.h" 5549887Snsayer 5681965Smarkmstatic void adjust(char keyout[HEXKEYBYTES+1], char *keyin); 5781965Smarkm 5849887Snsayer/* 5949887Snsayer * Choose top 128 bits of the common key to use as our idea key. 6049887Snsayer */ 6181965Smarkmstatic void 6281965Smarkmextractideakey(MINT *ck, IdeaData *ideakey) 6349887Snsayer{ 6449887Snsayer MINT *a; 6549887Snsayer MINT *z; 6649887Snsayer short r; 6749887Snsayer int i; 6849887Snsayer short base = (1 << 8); 6949887Snsayer char *k; 7049887Snsayer 71189092Sed z = mp_itom(0); 72189092Sed a = mp_itom(0); 73189092Sed mp_madd(ck, z, a); 7449887Snsayer for (i = 0; i < ((KEYSIZE - 128) / 8); i++) { 75189092Sed mp_sdiv(a, base, a, &r); 7649887Snsayer } 7749887Snsayer k = (char *)ideakey; 7849887Snsayer for (i = 0; i < 16; i++) { 79189092Sed mp_sdiv(a, base, a, &r); 8049887Snsayer *k++ = r; 8149887Snsayer } 82189092Sed mp_mfree(z); 83189092Sed mp_mfree(a); 8449887Snsayer} 8549887Snsayer 8649887Snsayer/* 8749887Snsayer * Choose middle 64 bits of the common key to use as our des key, possibly 8849887Snsayer * overwriting the lower order bits by setting parity. 8949887Snsayer */ 9081965Smarkmstatic void 9181965Smarkmextractdeskey(MINT *ck, DesData *deskey) 9249887Snsayer{ 9349887Snsayer MINT *a; 9449887Snsayer MINT *z; 9549887Snsayer short r; 9649887Snsayer int i; 9749887Snsayer short base = (1 << 8); 9849887Snsayer char *k; 9949887Snsayer 100189092Sed z = mp_itom(0); 101189092Sed a = mp_itom(0); 102189092Sed mp_madd(ck, z, a); 10349887Snsayer for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) { 104189092Sed mp_sdiv(a, base, a, &r); 10549887Snsayer } 10649887Snsayer k = (char *)deskey; 10749887Snsayer for (i = 0; i < 8; i++) { 108189092Sed mp_sdiv(a, base, a, &r); 10949887Snsayer *k++ = r; 11049887Snsayer } 111189092Sed mp_mfree(z); 112189092Sed mp_mfree(a); 11349887Snsayer} 11449887Snsayer 11549887Snsayer/* 11649887Snsayer * get common key from my secret key and his public key 11749887Snsayer */ 11881965Smarkmvoid 11981965Smarkmcommon_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey) 12049887Snsayer{ 12149887Snsayer MINT *public; 12249887Snsayer MINT *secret; 12349887Snsayer MINT *common; 124189092Sed MINT *modulus = mp_xtom(HEXMODULUS); 12549887Snsayer 126189092Sed public = mp_xtom(xpublic); 127189092Sed secret = mp_xtom(xsecret); 128189092Sed common = mp_itom(0); 129189092Sed mp_pow(public, secret, modulus, common); 13049887Snsayer extractdeskey(common, deskey); 13149887Snsayer extractideakey(common, ideakey); 13249887Snsayer des_set_odd_parity(deskey); 133189092Sed mp_mfree(common); 134189092Sed mp_mfree(secret); 135189092Sed mp_mfree(public); 136189092Sed mp_mfree(modulus); 13749887Snsayer} 13849887Snsayer 13949887Snsayer/* 14049887Snsayer * Generate a seed 14149887Snsayer */ 14287139Smarkmstatic void 14381965Smarkmgetseed(char *seed, int seedsize) 14449887Snsayer{ 14576711Speter int i; 14676711Speter 14776691Snsayer srandomdev(); 14876691Snsayer for (i = 0; i < seedsize; i++) { 14976691Snsayer seed[i] = random() & 0xff; 15076691Snsayer } 15149887Snsayer} 15249887Snsayer 15349887Snsayer/* 15449887Snsayer * Generate a random public/secret key pair 15549887Snsayer */ 15681965Smarkmvoid 15781965Smarkmgenkeys(char *public, char *secret) 15849887Snsayer{ 15987139Smarkm size_t i; 16049887Snsayer 16149887Snsayer# define BASEBITS (8*sizeof(short) - 1) 16249887Snsayer# define BASE (1 << BASEBITS) 16349887Snsayer 164189092Sed MINT *pk = mp_itom(0); 165189092Sed MINT *sk = mp_itom(0); 16649887Snsayer MINT *tmp; 167189092Sed MINT *base = mp_itom(BASE); 168189092Sed MINT *root = mp_itom(PROOT); 169189092Sed MINT *modulus = mp_xtom(HEXMODULUS); 17049887Snsayer short r; 17149887Snsayer unsigned short seed[KEYSIZE/BASEBITS + 1]; 17249887Snsayer char *xkey; 17349887Snsayer 17449887Snsayer getseed((char *)seed, sizeof(seed)); 17549887Snsayer for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) { 17649887Snsayer r = seed[i] % BASE; 177189092Sed tmp = mp_itom(r); 178189092Sed mp_mult(sk, base, sk); 179189092Sed mp_madd(sk, tmp, sk); 180189092Sed mp_mfree(tmp); 18149887Snsayer } 182189092Sed tmp = mp_itom(0); 183189092Sed mp_mdiv(sk, modulus, tmp, sk); 184189092Sed mp_mfree(tmp); 185189092Sed mp_pow(root, sk, modulus, pk); 186189092Sed xkey = mp_mtox(sk); 18749887Snsayer adjust(secret, xkey); 188189092Sed xkey = mp_mtox(pk); 18949887Snsayer adjust(public, xkey); 190189092Sed mp_mfree(sk); 191189092Sed mp_mfree(base); 192189092Sed mp_mfree(pk); 193189092Sed mp_mfree(root); 194189092Sed mp_mfree(modulus); 19549887Snsayer} 19649887Snsayer 19749887Snsayer/* 19849887Snsayer * Adjust the input key so that it is 0-filled on the left 19949887Snsayer */ 20081965Smarkmstatic void 20181965Smarkmadjust(char keyout[HEXKEYBYTES+1], char *keyin) 20249887Snsayer{ 20349887Snsayer char *p; 20449887Snsayer char *s; 20549887Snsayer 20649887Snsayer for (p = keyin; *p; p++) 20749887Snsayer ; 20849887Snsayer for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) { 20949887Snsayer *s = *p; 21049887Snsayer } 21149887Snsayer while (s >= keyout) { 21249887Snsayer *s-- = '0'; 21349887Snsayer } 21449887Snsayer} 21549887Snsayer 21649887Snsayerstatic char hextab[17] = "0123456789ABCDEF"; 21749887Snsayer 21849887Snsayer/* given a DES key, cbc encrypt and translate input to terminated hex */ 21981965Smarkmvoid 22081965Smarkmpk_encode(char *in, char *out, DesData *key) 22149887Snsayer{ 22249887Snsayer char buf[256]; 22349887Snsayer DesData i; 22449887Snsayer des_key_schedule k; 22549887Snsayer int l,op,deslen; 22649887Snsayer 22749887Snsayer memset(&i,0,sizeof(i)); 22849887Snsayer memset(buf,0,sizeof(buf)); 22949887Snsayer deslen = ((strlen(in) + 7)/8)*8; 23049887Snsayer des_key_sched(key, k); 23176711Speter des_cbc_encrypt(in,buf,deslen, k,&i,DES_ENCRYPT); 23249887Snsayer for (l=0,op=0;l<deslen;l++) { 23349887Snsayer out[op++] = hextab[(buf[l] & 0xf0) >> 4]; 23449887Snsayer out[op++] = hextab[(buf[l] & 0x0f)]; 23549887Snsayer } 23649887Snsayer out[op] = '\0'; 23749887Snsayer} 23849887Snsayer 23949887Snsayer/* given a DES key, translate input from hex and decrypt */ 24081965Smarkmvoid 24181965Smarkmpk_decode(char *in, char *out, DesData *key) 24249887Snsayer{ 24349887Snsayer char buf[256]; 24449887Snsayer DesData i; 24549887Snsayer des_key_schedule k; 24687139Smarkm int n1,n2,op; 24787139Smarkm size_t l; 24849887Snsayer 24949887Snsayer memset(&i,0,sizeof(i)); 25049887Snsayer memset(buf,0,sizeof(buf)); 25149887Snsayer for (l=0,op=0;l<strlen(in)/2;l++,op+=2) { 25249887Snsayer if (in[op] > '9') 25349887Snsayer n1 = in[op] - 'A' + 10; 25449887Snsayer else 25549887Snsayer n1 = in[op] - '0'; 25649887Snsayer if (in[op+1] > '9') 25749887Snsayer n2 = in[op+1] - 'A' + 10; 25849887Snsayer else 25949887Snsayer n2 = in[op+1] - '0'; 26049887Snsayer buf[l] = n1*16 +n2; 26149887Snsayer } 26249887Snsayer des_key_sched(key, k); 26376711Speter des_cbc_encrypt(buf,out,strlen(in)/2, k,&i,DES_DECRYPT); 26449887Snsayer out[strlen(in)/2] = '\0'; 26549887Snsayer} 266