212 lines
4.5 KiB
C
Executable File
212 lines
4.5 KiB
C
Executable File
|
|
/*
|
|
* Fast DES evaluation & benchmarking for UNIX
|
|
* Compares output of fencrypt()/fsetkey() with UNIX crypt()/encrypt()/setkey()
|
|
* and measures speed using times().
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#if USG
|
|
#include <sys/types.h>
|
|
#endif /*USG*/
|
|
#include <sys/param.h> /* for HZ */
|
|
#include <sys/times.h>
|
|
|
|
#include <crypt.h>
|
|
|
|
#include "des56.h"
|
|
|
|
typedef struct {
|
|
char b[8];
|
|
} chunk;
|
|
|
|
#ifdef CRAY
|
|
# define USG 1
|
|
#endif /*CRAY*/
|
|
|
|
#ifndef USG
|
|
# define USG 0
|
|
#endif /*!USG*/
|
|
|
|
#if BSD >= 43 && defined(vax) && !defined(HZ)
|
|
# define HZ 100
|
|
#endif
|
|
|
|
|
|
char *
|
|
bprint(char b[64])
|
|
{
|
|
static char s[17];
|
|
register int i;
|
|
|
|
for(i = 0; i < 64; i += 4)
|
|
sprintf(&s[i/4], "%1x", b[i]<<3 | b[i+1]<<2 | b[i+2]<<1 | b[i+3]);
|
|
return(s);
|
|
}
|
|
|
|
char *
|
|
wprint(chunk *v)
|
|
{
|
|
static char s[17];
|
|
register int i;
|
|
|
|
for(i = 0; i < 8; i++)
|
|
sprintf(&s[2*i], "%02x", v->b[i] & 0xff);
|
|
return(s);
|
|
}
|
|
|
|
void getv(char *s, chunk *v)
|
|
{
|
|
register int i, t;
|
|
|
|
if(s[0] == '0' && s[1] == 'x')
|
|
s += 2;
|
|
for(i = 0; i < 8; i++) {
|
|
t = 0;
|
|
if(*s >= '0' && *s <= '9') t = *s++ - '0';
|
|
else if(*s >= 'a' && *s <= 'f') t = *s++ - 'a' + 10;
|
|
else if(*s >= 'A' && *s <= 'F') t = *s++ - 'A' + 10;
|
|
t <<= 4;
|
|
if(*s >= '0' && *s <= '9') t |= *s++ - '0';
|
|
else if(*s >= 'a' && *s <= 'f') t |= *s++ - 'a' + 10;
|
|
else if(*s >= 'A' && *s <= 'F') t |= *s++ - 'A' + 10;
|
|
v->b[i] = t;
|
|
if(*s == '.') {
|
|
s++;
|
|
i = 4-1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void expand(chunk *v, char bits[64])
|
|
{
|
|
register unsigned int i;
|
|
|
|
for(i = 0; i < 64; i++)
|
|
bits[i] = (v->b[i/8] >> (7 - i%8)) & 1;
|
|
}
|
|
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
register int i;
|
|
chunk key, olddata, newdata;
|
|
char bkey[64], bdata[64];
|
|
int decrypt = 0;
|
|
keysched KS;
|
|
|
|
if(argc < 2 || argv[1][0] == '-') {
|
|
|
|
usage:
|
|
printf("\
|
|
Usage: %s key [ -{ckCK} count ] [ data ... ]\n\
|
|
Demonstrate and/or time fast DES routines.\n\
|
|
``key'' and ``data'' are left-justified, 0-padded hex values <= 16 digits\n\
|
|
By default, encrypts & decrypts each 'data' block with both fastdes and\n\
|
|
crypt() library DES routines to show equality.\n\
|
|
-c N encrypt N times using fast DES\n\
|
|
-k N set-key N times using fast DES\n\
|
|
-C N encrypt N times using library DES\n\
|
|
%s",
|
|
argv[0],
|
|
USG ? "" : "\
|
|
-K N set-key N times using library DES\n");
|
|
exit(1);
|
|
}
|
|
|
|
getv(argv[1], &key);
|
|
fsetkey(key.b, &KS);
|
|
expand(&key, bkey);
|
|
#if USG
|
|
/* System V systems don't seem to have setkey, just crypt
|
|
* so we use that to set the key.
|
|
*/
|
|
for(i = 0; i < 8; i++)
|
|
bdata[i] = (key.b[i] >> 1) | 0x80;
|
|
bdata[8] = '\0';
|
|
crypt((char *)bdata, ".."); /* Key, no salt */
|
|
#else /*!USG*/
|
|
setkey(bkey);
|
|
#endif /*!USG*/
|
|
printf("key\t%s\n", bprint(bkey));
|
|
|
|
for(i = 2; i < argc; i++) {
|
|
if(argv[i][0] == '-') {
|
|
int count, n;
|
|
char c, *op;
|
|
struct tms now, then;
|
|
|
|
c = argv[i][1];
|
|
op = &argv[i][2];
|
|
if(*op == '\0')
|
|
if((op = argv[++i]) == NULL)
|
|
goto usage;
|
|
count = atoi(op);
|
|
if(count <= 0)
|
|
count = 1;
|
|
n = count;
|
|
expand(&olddata, bdata);
|
|
times(&now);
|
|
switch(c) {
|
|
case 'c':
|
|
op = "fencrypt";
|
|
do fencrypt(newdata.b, 0, &KS); while(--n > 0); break;
|
|
case 'k':
|
|
op = "fsetkey";
|
|
do fsetkey(key.b, &KS); while(--n > 0); break;
|
|
|
|
case 'C':
|
|
op = "library encrypt";
|
|
do encrypt(bdata, decrypt); while(--n > 0); break;
|
|
|
|
case 'K':
|
|
#if USG
|
|
printf("UNIX library has no setkey() function on this system\n");
|
|
continue;
|
|
#else /*!USG*/
|
|
op = "library setkey";
|
|
do setkey(bkey); while(--n > 0); break;
|
|
#endif /*!USG*/
|
|
|
|
default:
|
|
printf("Unknown option -%c\n", c);
|
|
goto usage;
|
|
}
|
|
times(&then);
|
|
n = then.tms_utime - now.tms_utime;
|
|
printf("%d %s's in %0.2f seconds (%.2f us apiece)\n",
|
|
count, op, (float) n / HZ,
|
|
(1.0e6 * n / (HZ * count)));
|
|
} else {
|
|
/* Demonstrate that it works for a particular data block.
|
|
* To compare with UNIX encrypt(), we must play its game.
|
|
* On BSD systems, encrypt(block, 1) is the inverse of (..., 0)
|
|
* but on USG systems the second parameter is ignored and
|
|
* encrypt(block, x) always encrypts.
|
|
*/
|
|
getv(argv[i], &olddata);
|
|
newdata = olddata;
|
|
|
|
printf("\tOriginal data\t\tEncrypted\t\t%s\n",
|
|
USG ? "Encrypted again" : "Decrypted");
|
|
|
|
printf("fastdes\t%s", wprint(&olddata));
|
|
fencrypt(newdata.b, 0, &KS);
|
|
printf("\t%s", wprint(&newdata));
|
|
fencrypt(newdata.b, USG ? 0 : 1, &KS);
|
|
printf("\t%s\n", wprint(&newdata));
|
|
|
|
expand(&olddata, bdata);
|
|
printf("UNIXdes\t%s", bprint(bdata));
|
|
encrypt(bdata, 0);
|
|
printf("\t%s", bprint(bdata));
|
|
encrypt(bdata, USG ? 0 : 1);
|
|
printf("\t%s\n", bprint(bdata));
|
|
}
|
|
}
|
|
exit(0);
|
|
}
|
|
|