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
310f8c8396SNick Sayer /* public key routines */
320f8c8396SNick Sayer /* functions:
330f8c8396SNick Sayer genkeys(char *public, char *secret)
340f8c8396SNick Sayer common_key(char *secret, char *public, desData *deskey)
350f8c8396SNick Sayer pk_encode(char *in, *out, DesData *deskey);
360f8c8396SNick Sayer pk_decode(char *in, *out, DesData *deskey);
370f8c8396SNick Sayer where
380f8c8396SNick Sayer char public[HEXKEYBYTES + 1];
390f8c8396SNick Sayer char secret[HEXKEYBYTES + 1];
400f8c8396SNick Sayer */
410f8c8396SNick Sayer
420f8c8396SNick Sayer #include <sys/time.h>
43bf4f84d4SMark Murray #include <openssl/des.h>
4421f083c0SMark Murray #include <fcntl.h>
4521f083c0SMark Murray #include <stdio.h>
468fa113e5SMark Murray #include <stdlib.h>
4721f083c0SMark Murray #include <string.h>
488fa113e5SMark Murray
490f8c8396SNick Sayer #include "mp.h"
500f8c8396SNick Sayer #include "pk.h"
510f8c8396SNick Sayer
5221f083c0SMark Murray static void adjust(char keyout[HEXKEYBYTES+1], char *keyin);
5321f083c0SMark Murray
540f8c8396SNick Sayer /*
550f8c8396SNick Sayer * Choose top 128 bits of the common key to use as our idea key.
560f8c8396SNick Sayer */
5721f083c0SMark Murray static void
extractideakey(MINT * ck,IdeaData * ideakey)5821f083c0SMark Murray extractideakey(MINT *ck, IdeaData *ideakey)
590f8c8396SNick Sayer {
600f8c8396SNick Sayer MINT *a;
610f8c8396SNick Sayer MINT *z;
620f8c8396SNick Sayer short r;
630f8c8396SNick Sayer int i;
640f8c8396SNick Sayer short base = (1 << 8);
650f8c8396SNick Sayer char *k;
660f8c8396SNick Sayer
67b3aaa0ccSEd Schouten z = mp_itom(0);
68b3aaa0ccSEd Schouten a = mp_itom(0);
69b3aaa0ccSEd Schouten mp_madd(ck, z, a);
700f8c8396SNick Sayer for (i = 0; i < ((KEYSIZE - 128) / 8); i++) {
71b3aaa0ccSEd Schouten mp_sdiv(a, base, a, &r);
720f8c8396SNick Sayer }
730f8c8396SNick Sayer k = (char *)ideakey;
740f8c8396SNick Sayer for (i = 0; i < 16; i++) {
75b3aaa0ccSEd Schouten mp_sdiv(a, base, a, &r);
760f8c8396SNick Sayer *k++ = r;
770f8c8396SNick Sayer }
78b3aaa0ccSEd Schouten mp_mfree(z);
79b3aaa0ccSEd Schouten mp_mfree(a);
800f8c8396SNick Sayer }
810f8c8396SNick Sayer
820f8c8396SNick Sayer /*
830f8c8396SNick Sayer * Choose middle 64 bits of the common key to use as our des key, possibly
840f8c8396SNick Sayer * overwriting the lower order bits by setting parity.
850f8c8396SNick Sayer */
8621f083c0SMark Murray static void
extractdeskey(MINT * ck,DesData * deskey)8721f083c0SMark Murray extractdeskey(MINT *ck, DesData *deskey)
880f8c8396SNick Sayer {
890f8c8396SNick Sayer MINT *a;
900f8c8396SNick Sayer MINT *z;
910f8c8396SNick Sayer short r;
920f8c8396SNick Sayer int i;
930f8c8396SNick Sayer short base = (1 << 8);
940f8c8396SNick Sayer char *k;
950f8c8396SNick Sayer
96b3aaa0ccSEd Schouten z = mp_itom(0);
97b3aaa0ccSEd Schouten a = mp_itom(0);
98b3aaa0ccSEd Schouten mp_madd(ck, z, a);
990f8c8396SNick Sayer for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) {
100b3aaa0ccSEd Schouten mp_sdiv(a, base, a, &r);
1010f8c8396SNick Sayer }
1020f8c8396SNick Sayer k = (char *)deskey;
1030f8c8396SNick Sayer for (i = 0; i < 8; i++) {
104b3aaa0ccSEd Schouten mp_sdiv(a, base, a, &r);
1050f8c8396SNick Sayer *k++ = r;
1060f8c8396SNick Sayer }
107b3aaa0ccSEd Schouten mp_mfree(z);
108b3aaa0ccSEd Schouten mp_mfree(a);
1090f8c8396SNick Sayer }
1100f8c8396SNick Sayer
1110f8c8396SNick Sayer /*
1120f8c8396SNick Sayer * get common key from my secret key and his public key
1130f8c8396SNick Sayer */
11421f083c0SMark Murray void
common_key(char * xsecret,char * xpublic,IdeaData * ideakey,DesData * deskey)11521f083c0SMark Murray common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey)
1160f8c8396SNick Sayer {
1170f8c8396SNick Sayer MINT *public;
1180f8c8396SNick Sayer MINT *secret;
1190f8c8396SNick Sayer MINT *common;
120b3aaa0ccSEd Schouten MINT *modulus = mp_xtom(HEXMODULUS);
1210f8c8396SNick Sayer
122b3aaa0ccSEd Schouten public = mp_xtom(xpublic);
123b3aaa0ccSEd Schouten secret = mp_xtom(xsecret);
124b3aaa0ccSEd Schouten common = mp_itom(0);
125b3aaa0ccSEd Schouten mp_pow(public, secret, modulus, common);
1260f8c8396SNick Sayer extractdeskey(common, deskey);
1270f8c8396SNick Sayer extractideakey(common, ideakey);
128b285c5dfSJung-uk Kim DES_set_odd_parity(deskey);
129b3aaa0ccSEd Schouten mp_mfree(common);
130b3aaa0ccSEd Schouten mp_mfree(secret);
131b3aaa0ccSEd Schouten mp_mfree(public);
132b3aaa0ccSEd Schouten mp_mfree(modulus);
1330f8c8396SNick Sayer }
1340f8c8396SNick Sayer
1350f8c8396SNick Sayer /*
1360f8c8396SNick Sayer * Generate a seed
1370f8c8396SNick Sayer */
1388fa113e5SMark Murray static void
getseed(char * seed,int seedsize)13921f083c0SMark Murray getseed(char *seed, int seedsize)
1400f8c8396SNick Sayer {
141*23c30549SConrad Meyer arc4random_buf(seed, seedsize);
1420f8c8396SNick Sayer }
1430f8c8396SNick Sayer
1440f8c8396SNick Sayer /*
1450f8c8396SNick Sayer * Generate a random public/secret key pair
1460f8c8396SNick Sayer */
14721f083c0SMark Murray void
genkeys(char * public,char * secret)14821f083c0SMark Murray genkeys(char *public, char *secret)
1490f8c8396SNick Sayer {
1508fa113e5SMark Murray size_t i;
1510f8c8396SNick Sayer
1520f8c8396SNick Sayer # define BASEBITS (8*sizeof(short) - 1)
1530f8c8396SNick Sayer # define BASE (1 << BASEBITS)
1540f8c8396SNick Sayer
155b3aaa0ccSEd Schouten MINT *pk = mp_itom(0);
156b3aaa0ccSEd Schouten MINT *sk = mp_itom(0);
1570f8c8396SNick Sayer MINT *tmp;
158c4326258SDimitry Andric MINT *base = mp_itom((short)BASE);
159b3aaa0ccSEd Schouten MINT *root = mp_itom(PROOT);
160b3aaa0ccSEd Schouten MINT *modulus = mp_xtom(HEXMODULUS);
1610f8c8396SNick Sayer short r;
1620f8c8396SNick Sayer unsigned short seed[KEYSIZE/BASEBITS + 1];
1630f8c8396SNick Sayer char *xkey;
1640f8c8396SNick Sayer
1650f8c8396SNick Sayer getseed((char *)seed, sizeof(seed));
1660f8c8396SNick Sayer for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) {
1670f8c8396SNick Sayer r = seed[i] % BASE;
168b3aaa0ccSEd Schouten tmp = mp_itom(r);
169b3aaa0ccSEd Schouten mp_mult(sk, base, sk);
170b3aaa0ccSEd Schouten mp_madd(sk, tmp, sk);
171b3aaa0ccSEd Schouten mp_mfree(tmp);
1720f8c8396SNick Sayer }
173b3aaa0ccSEd Schouten tmp = mp_itom(0);
174b3aaa0ccSEd Schouten mp_mdiv(sk, modulus, tmp, sk);
175b3aaa0ccSEd Schouten mp_mfree(tmp);
176b3aaa0ccSEd Schouten mp_pow(root, sk, modulus, pk);
177b3aaa0ccSEd Schouten xkey = mp_mtox(sk);
1780f8c8396SNick Sayer adjust(secret, xkey);
179b3aaa0ccSEd Schouten xkey = mp_mtox(pk);
1800f8c8396SNick Sayer adjust(public, xkey);
181b3aaa0ccSEd Schouten mp_mfree(sk);
182b3aaa0ccSEd Schouten mp_mfree(base);
183b3aaa0ccSEd Schouten mp_mfree(pk);
184b3aaa0ccSEd Schouten mp_mfree(root);
185b3aaa0ccSEd Schouten mp_mfree(modulus);
1860f8c8396SNick Sayer }
1870f8c8396SNick Sayer
1880f8c8396SNick Sayer /*
1890f8c8396SNick Sayer * Adjust the input key so that it is 0-filled on the left
1900f8c8396SNick Sayer */
19121f083c0SMark Murray static void
adjust(char keyout[HEXKEYBYTES+1],char * keyin)19221f083c0SMark Murray adjust(char keyout[HEXKEYBYTES+1], char *keyin)
1930f8c8396SNick Sayer {
1940f8c8396SNick Sayer char *p;
1950f8c8396SNick Sayer char *s;
1960f8c8396SNick Sayer
1970f8c8396SNick Sayer for (p = keyin; *p; p++)
1980f8c8396SNick Sayer ;
1990f8c8396SNick Sayer for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) {
2000f8c8396SNick Sayer *s = *p;
2010f8c8396SNick Sayer }
2020f8c8396SNick Sayer while (s >= keyout) {
2030f8c8396SNick Sayer *s-- = '0';
2040f8c8396SNick Sayer }
2050f8c8396SNick Sayer }
2060f8c8396SNick Sayer
2070f8c8396SNick Sayer static char hextab[17] = "0123456789ABCDEF";
2080f8c8396SNick Sayer
2090f8c8396SNick Sayer /* given a DES key, cbc encrypt and translate input to terminated hex */
21021f083c0SMark Murray void
pk_encode(char * in,char * out,DesData * key)21121f083c0SMark Murray pk_encode(char *in, char *out, DesData *key)
2120f8c8396SNick Sayer {
2130f8c8396SNick Sayer char buf[256];
2140f8c8396SNick Sayer DesData i;
215b285c5dfSJung-uk Kim DES_key_schedule k;
2160f8c8396SNick Sayer int l,op,deslen;
2170f8c8396SNick Sayer
2180f8c8396SNick Sayer memset(&i,0,sizeof(i));
2190f8c8396SNick Sayer memset(buf,0,sizeof(buf));
2200f8c8396SNick Sayer deslen = ((strlen(in) + 7)/8)*8;
221b285c5dfSJung-uk Kim DES_key_sched(key, &k);
222b285c5dfSJung-uk Kim DES_cbc_encrypt(in, buf, deslen, &k, &i, DES_ENCRYPT);
2230f8c8396SNick Sayer for (l=0,op=0;l<deslen;l++) {
2240f8c8396SNick Sayer out[op++] = hextab[(buf[l] & 0xf0) >> 4];
2250f8c8396SNick Sayer out[op++] = hextab[(buf[l] & 0x0f)];
2260f8c8396SNick Sayer }
2270f8c8396SNick Sayer out[op] = '\0';
2280f8c8396SNick Sayer }
2290f8c8396SNick Sayer
2300f8c8396SNick Sayer /* given a DES key, translate input from hex and decrypt */
23121f083c0SMark Murray void
pk_decode(char * in,char * out,DesData * key)23221f083c0SMark Murray pk_decode(char *in, char *out, DesData *key)
2330f8c8396SNick Sayer {
2340f8c8396SNick Sayer char buf[256];
2350f8c8396SNick Sayer DesData i;
236b285c5dfSJung-uk Kim DES_key_schedule k;
2378fa113e5SMark Murray int n1,n2,op;
2388fa113e5SMark Murray size_t l;
2390f8c8396SNick Sayer
2400f8c8396SNick Sayer memset(&i,0,sizeof(i));
2410f8c8396SNick Sayer memset(buf,0,sizeof(buf));
2420f8c8396SNick Sayer for (l=0,op=0;l<strlen(in)/2;l++,op+=2) {
2430f8c8396SNick Sayer if (in[op] > '9')
2440f8c8396SNick Sayer n1 = in[op] - 'A' + 10;
2450f8c8396SNick Sayer else
2460f8c8396SNick Sayer n1 = in[op] - '0';
2470f8c8396SNick Sayer if (in[op+1] > '9')
2480f8c8396SNick Sayer n2 = in[op+1] - 'A' + 10;
2490f8c8396SNick Sayer else
2500f8c8396SNick Sayer n2 = in[op+1] - '0';
2510f8c8396SNick Sayer buf[l] = n1*16 +n2;
2520f8c8396SNick Sayer }
253b285c5dfSJung-uk Kim DES_key_sched(key, &k);
254b285c5dfSJung-uk Kim DES_cbc_encrypt(buf, out, strlen(in) / 2, &k, &i, DES_DECRYPT);
2550f8c8396SNick Sayer out[strlen(in)/2] = '\0';
2560f8c8396SNick Sayer }
257