Major bug in /usr/src/lib/libc/gen/crypt.c

terryl at tekcrl.UUCP terryl at tekcrl.UUCP
Wed Nov 12 11:01:17 AEST 1986


     Below is an excerpt from the function encrypt() found in the file named
in the Subject: line.


/*
 * Initial permutation,
 */
static	char	IP[] = {
	58,50,42,34,26,18,10, 2,
	60,52,44,36,28,20,12, 4,
	62,54,46,38,30,22,14, 6,
	64,56,48,40,32,24,16, 8,
	57,49,41,33,25,17, 9, 1,
	59,51,43,35,27,19,11, 3,
	61,53,45,37,29,21,13, 5,
	63,55,47,39,31,23,15, 7,
};

/*
 * Final permutation, FP = IP^(-1)
 */
static	char	FP[] = {
	40, 8,48,16,56,24,64,32,
	39, 7,47,15,55,23,63,31,
	38, 6,46,14,54,22,62,30,
	37, 5,45,13,53,21,61,29,
	36, 4,44,12,52,20,60,28,
	35, 3,43,11,51,19,59,27,
	34, 2,42,10,50,18,58,26,
	33, 1,41, 9,49,17,57,25,
};
/*
 * The current block, divided into 2 halves.
 */
static	char	L[32], R[32];
static	char	tempL[32];
static	char	f[32];
/*
 * The payoff: encrypt a block.
 */

encrypt(block, edflag)
char *block;
{
	int i, ii;
	register t, j, k;

	/*
	 * First, permute the bits in the input
	 */
	for (j=0; j<64; j++)
		L[j] = block[IP[j]-1];
	/*
	 * Many lines deleted for brevity.......
	 */
	/*
	 * The final output
	 * gets the inverse permutation of the very original.
	 */
	for (j=0; j<64; j++)
		block[j] = L[FP[j]-1];
}

      What's the bug you ask??? Well, in both for loops the static array L is
is accessed from 0 to 63, directly in the first loop, and indirectly through
the array FP in the second loop. But L was declared to only have 32 elements
to begin with!!! This code is assuming that because the arrays L and R were
declared one after the other, their final addresses (and hence the storage they
occupy) will also be consecutive. Well, for most compilers, that's probably
true, but that's a pretty bad assumption to be made (read we just got bit by
this by our compiler). The fix is actually simple enough: just get rid of the
static array R, make the static array L 64 elements long, and declare a pointer
variable R in encrypt initialized with the address of the 32nd element of L,
like so:

	register char *R = &L[32];



More information about the Comp.bugs.4bsd.ucb-fixes mailing list