⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bdes.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1991, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Matt Bishop of Dartmouth College. * * The United States Government has rights in this work pursuant * to contract no. NAG 2-680 between the National Aeronautics and * Space Administration and Dartmouth College. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1991, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)bdes.c	8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * BDES -- DES encryption package for Berkeley Software Distribution 4.4 * options: *	-a	key is in ASCII *	-b	use ECB (electronic code book) mode *	-d	invert (decrypt) input *	-f b	use b-bit CFB (cipher feedback) mode *	-F b	use b-bit CFB (cipher feedback) alternative mode *	-k key	use key as the cryptographic key *	-m b	generate a MAC of length b *	-o b	use b-bit OFB (output feedback) mode *	-p	don't reset the parity bit *	-v v	use v as the initialization vector (ignored for ECB) * note: the last character of the last block is the integer indicating * how many characters of that block are to be output * * Author: Matt Bishop *	   Department of Mathematics and Computer Science *	   Dartmouth College *	   Hanover, NH  03755 * Email:  Matt.Bishop@dartmouth.edu *	   ...!decvax!dartvax!Matt.Bishop * * See Technical Report PCS-TR91-158, Department of Mathematics and Computer * Science, Dartmouth College, for a detailed description of the implemen- * tation and differences between it and Sun's.  The DES is described in * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page * or the technical report for a complete reference). */#include <errno.h>#include <unistd.h>#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>/* * BSD and System V systems offer special library calls that do * block moves and fills, so if possible we take advantage of them */#define	MEMCPY(dest,src,len)	bcopy((src),(dest),(len))#define	MEMZERO(dest,len)	bzero((dest),(len))/* Hide the calls to the primitive encryption routines. */#define	FASTWAY#ifdef	FASTWAY#define	DES_KEY(buf) \	if (des_setkey(buf)) \		err("des_setkey", 0);#define	DES_XFORM(buf) \	if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \		err("des_cipher", 0);#else#define	DES_KEY(buf)	{						\				char bits1[64];	/* bits of key */	\				expand(buf, bits1);			\				if (setkey(bits1))			\					err("setkey", 0);		\			}#define	DES_XFORM(buf)	{						\				char bits1[64];	/* bits of message */	\				expand(buf, bits1);			\				if (encrypt(bits1, inverse))		\					err("encrypt", 0);		\				compress(bits1, buf);			\			}#endif/* * this does an error-checking write */#define	READ(buf, n)	fread(buf, sizeof(char), n, stdin)#define WRITE(buf,n)						\		if (fwrite(buf, sizeof(char), n, stdout) != n)	\			err(bn, NULL);/* * some things to make references easier */typedef char Desbuf[8];#define	CHAR(x,i)	(x[i])#define	UCHAR(x,i)	(x[i])#define	BUFFER(x)	(x)#define	UBUFFER(x)	(x)/* * global variables and related macros */#define KEY_DEFAULT		0	/* interpret radix of key from key */#define KEY_ASCII		1	/* key is in ASCII characters */int keybase = KEY_DEFAULT;		/* how to interpret the key */enum { 					/* encrypt, decrypt, authenticate */	MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE} mode = MODE_ENCRYPT;enum {					/* ecb, cbc, cfb, cfba, ofb? */	ALG_ECB, ALG_CBC, ALG_CFB, ALG_OFB, ALG_CFBA} alg = ALG_CBC;Desbuf ivec;				/* initialization vector */char bits[] = {				/* used to extract bits from a char */	'\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'};int inverse;				/* 0 to encrypt, 1 to decrypt */int macbits = -1;			/* number of bits in authentication */int fbbits = -1;			/* number of feedback bits */int pflag;				/* 1 to preserve parity bits */main(ac, av)	int ac;				/* arg count */	char **av;			/* arg vector */{	extern int optind;		/* option (argument) number */	extern char *optarg;		/* argument to option if any */	register int i;			/* counter in a for loop */	register char *p;		/* used to obtain the key */	Desbuf msgbuf;			/* I/O buffer */	int kflag;			/* command-line encryptiooon key */	int argc;			/* the real arg count */	char **argv;			/* the real argument vector */	/*	 * Hide the arguments from ps(1) by making private copies of them	 * and clobbering the global (visible to ps(1)) ones.	 */	argc = ac;	ac = 1;	argv = malloc((argc + 1) * sizeof(char *));	for (i = 0; i < argc; ++i) {		argv[i] = strdup(av[i]);		MEMZERO(av[i], strlen(av[i]));	}	argv[argc] = NULL;	/* initialize the initialization vctor */	MEMZERO(ivec, 8);	/* process the argument list */	kflag = 0;	while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != EOF)		switch(i) {		case 'a':		/* key is ASCII */			keybase = KEY_ASCII;			break;		case 'b':		/* use ECB mode */			alg = ALG_ECB;			break;		case 'd':		/* decrypt */			mode = MODE_DECRYPT;			break;		case 'F':		/* use alternative CFB mode */			alg = ALG_CFBA;			if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0)				err(-1, "-F: number must be 1-56 inclusive");			else if (fbbits == -1)				err(-1, "-F: number must be a multiple of 7");			break;		case 'f':		/* use CFB mode */			alg = ALG_CFB;			if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)				err(-1, "-f: number must be 1-64 inclusive");			else if (fbbits == -1)				err(-1, "-f: number must be a multiple of 8");			break;		case 'k':		/* encryption key */			kflag = 1;			cvtkey(BUFFER(msgbuf), optarg);			break;		case 'm':		/* number of bits for MACing */			mode = MODE_AUTHENTICATE;			if ((macbits = setbits(optarg, 1)) > 64)				err(-1, "-m: number must be 0-64 inclusive");			break;		case 'o':		/* use OFB mode */			alg = ALG_OFB;			if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)				err(-1, "-o: number must be 1-64 inclusive");			else if (fbbits == -1)				err(-1, "-o: number must be a multiple of 8");			break;		case 'p':		/* preserve parity bits */			pflag = 1;			break;		case 'v':		/* set initialization vector */			cvtkey(BUFFER(ivec), optarg);			break;		default:		/* error */			usage();		}	if (!kflag) {		/*		 * if the key's not ASCII, assume it is		 */		keybase = KEY_ASCII;		/*		 * get the key		 */		p = getpass("Enter key: ");		/*		 * copy it, nul-padded, into the key area		 */		cvtkey(BUFFER(msgbuf), p);	}	makekey(msgbuf);	inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT;	switch(alg) {	case ALG_CBC:		switch(mode) {		case MODE_AUTHENTICATE:	/* authenticate using CBC mode */			cbcauth();			break;		case MODE_DECRYPT:	/* decrypt using CBC mode */			cbcdec();			break;		case MODE_ENCRYPT:	/* encrypt using CBC mode */			cbcenc();			break;		}		break;	case ALG_CFB:		switch(mode) {		case MODE_AUTHENTICATE:	/* authenticate using CFB mode */			cfbauth();			break;		case MODE_DECRYPT:	/* decrypt using CFB mode */			cfbdec();			break;		case MODE_ENCRYPT:	/* encrypt using CFB mode */			cfbenc();			break;		}		break;	case ALG_CFBA:		switch(mode) {		case MODE_AUTHENTICATE:	/* authenticate using CFBA mode */			err(-1, "can't authenticate with CFBA mode");			break;		case MODE_DECRYPT:	/* decrypt using CFBA mode */			cfbadec();			break;		case MODE_ENCRYPT:	/* encrypt using CFBA mode */			cfbaenc();			break;		}		break;	case ALG_ECB:		switch(mode) {		case MODE_AUTHENTICATE:	/* authenticate using ECB mode */			err(-1, "can't authenticate with ECB mode");			break;		case MODE_DECRYPT:	/* decrypt using ECB mode */			ecbdec();			break;		case MODE_ENCRYPT:	/* encrypt using ECB mode */			ecbenc();			break;		}		break;	case ALG_OFB:		switch(mode) {		case MODE_AUTHENTICATE:	/* authenticate using OFB mode */			err(-1, "can't authenticate with OFB mode");			break;		case MODE_DECRYPT:	/* decrypt using OFB mode */			ofbdec();			break;		case MODE_ENCRYPT:	/* encrypt using OFB mode */			ofbenc();			break;		}		break;	}	exit(0);}/* * print a warning message and, possibly, terminate */err(n, s)	int n;			/* offending block number */	char *s;		/* the message */{	if (n > 0)		(void)fprintf(stderr, "bdes (block %d): ", n);	else		(void)fprintf(stderr, "bdes: ");	(void)fprintf(stderr, "%s\n", s ? s : strerror(errno));	exit(1);}/* * map a hex character to an integer */tobinhex(c, radix)	char c;			/* char to be converted */	int radix;		/* base (2 to 16) */{	switch(c) {	case '0':		return(0x0);	case '1':		return(0x1);	case '2':		return(radix > 2 ? 0x2 : -1);	case '3':		return(radix > 3 ? 0x3 : -1);	case '4':		return(radix > 4 ? 0x4 : -1);	case '5':		return(radix > 5 ? 0x5 : -1);	case '6':		return(radix > 6 ? 0x6 : -1);	case '7':		return(radix > 7 ? 0x7 : -1);	case '8':		return(radix > 8 ? 0x8 : -1);	case '9':		return(radix > 9 ? 0x9 : -1);	case 'A': case 'a':	return(radix > 10 ? 0xa : -1);	case 'B': case 'b':	return(radix > 11 ? 0xb : -1);	case 'C': case 'c':	return(radix > 12 ? 0xc : -1);	case 'D': case 'd':	return(radix > 13 ? 0xd : -1);	case 'E': case 'e':	return(radix > 14 ? 0xe : -1);	case 'F': case 'f':	return(radix > 15 ? 0xf : -1);	}	/*	 * invalid character	 */	return(-1);}/* * convert the key to a bit pattern */cvtkey(obuf, ibuf)	char *obuf;			/* bit pattern */	char *ibuf;			/* the key itself */{	register int i, j;		/* counter in a for loop */	int nbuf[64];			/* used for hex/key translation */	/*	 * just switch on the key base	 */	switch(keybase) {	case KEY_ASCII:			/* ascii to integer */		(void)strncpy(obuf, ibuf, 8);		return;	case KEY_DEFAULT:		/* tell from context */		/*		 * leading '0x' or '0X' == hex key		 */		if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {			ibuf = &ibuf[2];			/*			 * now translate it, bombing on any illegal hex digit			 */			for (i = 0; ibuf[i] && i < 16; i++)				if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1)					err(-1, "bad hex digit in key");			while (i < 16)				nbuf[i++] = 0;			for (i = 0; i < 8; i++)				obuf[i] =				    ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);			/* preserve parity bits */			pflag = 1;			return;		}		/*		 * leading '0b' or '0B' == binary key		 */		if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {			ibuf = &ibuf[2];			/*			 * now translate it, bombing on any illegal binary digit			 */			for (i = 0; ibuf[i] && i < 16; i++)				if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1)					err(-1, "bad binary digit in key");			while (i < 64)				nbuf[i++] = 0;			for (i = 0; i < 8; i++)				for (j = 0; j < 8; j++)					obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];			/* preserve parity bits */			pflag = 1;			return;		}		/*		 * no special leader -- ASCII		 */		(void)strncpy(obuf, ibuf, 8);	}}/* * convert an ASCII string into a decimal number: * 1. must be between 0 and 64 inclusive * 2. must be a valid decimal number * 3. must be a multiple of mult */setbits(s, mult)	char *s;			/* the ASCII string */	int mult;			/* what it must be a multiple of */{	register char *p;		/* pointer in a for loop */	register int n = 0;		/* the integer collected */	/*	 * skip white space	 */	while (isspace(*s))		s++;	/*	 * get the integer	 */	for (p = s; *p; p++) {		if (isdigit(*p))			n = n * 10 + *p - '0';		else {			err(-1, "bad decimal digit in MAC length");		}	}	/*	 * be sure it's a multiple of mult	 */	return((n % mult != 0) ? -1 : n);}/***************** * DES FUNCTIONS * *****************//* * This sets the DES key and (if you're using the deszip version) * the direction of the transformation.  This uses the Sun * to map the 64-bit key onto the 56 bits that the key schedule * generation routines use: the old way, which just uses the user- * supplied 64 bits as is, and the new way, which resets the parity * bit to be the same as the low-order bit in each character.  The * new way generates a greater variety of key schedules, since many * systems set the parity (high) bit of each character to 0, and the * DES ignores the low order bit of each character. */makekey(buf)	Desbuf buf;				/* key block */{	register int i, j;			/* counter in a for loop */	register int par;			/* parity counter */	/*	 * if the parity is not preserved, flip it	 */	if (!pflag) {		for (i = 0; i < 8; i++) {			par = 0;			for (j = 1; j < 8; j++)				if ((bits[j]&UCHAR(buf, i)) != 0)					par++;			if ((par&01) == 01)				UCHAR(buf, i) = UCHAR(buf, i)&0177;			else				UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;		}	}	DES_KEY(UBUFFER(buf));}/* * This encrypts using the Electronic Code Book mode of DES */ecbenc(){	register int n;		/* number of bytes actually read */	register int bn;	/* block number */	Desbuf msgbuf;		/* I/O buffer */	for (bn = 0; (n = READ(BUFFER(msgbuf),  8)) == 8; bn++) {		/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -