Re: Announce loop-AES-v1.3b file crypto package

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Jul 08, 2001 at 01:37:39AM -0700, IT3 Stuart B. Tener, USNR-R wrote:
> Ms. Harris, et al.:
> 
> Given such a methodology as described below: we start at 90bits of
> entropy, where do we end of if we fully implement this strategy?

You can have as many bits as you want if you're willing to use a
long enough passphrase.  At a certain point you'll have to start
writing them down, though.  This is probably OK if you're the average
forgetful Joe and the risk of irrevocably losing your data outweighs
the risk of someone violating the physical security of your home,
office safe deposit box, etc. order to get the passphrase.

It's not a good idea if you're a hard-core cypherpunk, are at risk
of law enforcement investigation or intrusive subpoena, or are just
playing with crypto because it's fun and don't have any important
data under encryption :-).

> As well, where do we end up if we create 5 pass phrases using the
> rules below, and each week we rotate from one of the five pass phrases?
> Exactly where do we end up?

Each passphrase is independent of all others, and should be secure.
Choosing how often to rotate passphrases is something else entirely;
it depends on your assessment of risk of compromise as a function
of time, severity of compromise, and risk associated with passphrase
changes.  I can't really comment on that.

> 
>         I am thinking of writing a piece of software (in C) to generate such
> passwords, has anyone thought about doing this? To do it I would need to
> draw an exact set of rules for the software to follow, can we narrow it down
> a bit, so that I can do this?

A program that implements the algorithm I described is attached.
It would be cool if folks on the list would check it over for
correctness.  This implementation loads the whole dictionary into
memory so be careful with those really huge dictionaries :-).

miket
/*
 * passphrase.c: Generate a random passphrase which can
 *               probably be memorized.
 *
 * Copyright 2001 Michael P. Touloumtzis.
 *
 * Available under the "BSD license":
 *
 * Permission is hereby granted, free of charge, to any
 * person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in
 * the Software without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice
 * shall be included in all copies or substantial portions
 * of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL MICHAEL P.
 * TOULOUMTZIS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define NUM_OUTPUT_WORDS 5
#define WORD_LENGTH_MIN 5
#define WORD_LENGTH_MAX 10

#define DICT_RANDOM_BITS 15
#define DICT_RANDOM_COUNT (1 << DICT_RANDOM_BITS)
#define DICT_RANDOM_MASK (DICT_RANDOM_COUNT - 1)

static char *exename;
static char *wordlist [DICT_RANDOM_COUNT];
static size_t wordlistsize = sizeof wordlist / sizeof *wordlist;

static FILE *ro_fopen(const char *pathname);
static int ro_open(const char *pathname);
static ssize_t xread(int fd, void *buf, size_t count);
static ssize_t xaread(int fd, void *buf, size_t count);
static char *xstrdup(const char *s);

/* load word array from word-per-line dictionary */
static void load_words(const char *dictname)
{
	char buf [128];	/* longer than any word */
	FILE *dict;
	size_t i = 0;

	dict = ro_fopen(dictname);
	while (i < wordlistsize && fgets(buf, sizeof buf, dict)) {
		size_t len;
		char *ptr;

		assert(strlen(buf) < sizeof buf);
		if ((ptr = strchr(buf, '\n')))
			*ptr = '\0';
		len = strlen(buf);
		if (len >= WORD_LENGTH_MIN && len <= WORD_LENGTH_MAX)
			wordlist[i++] = xstrdup(buf);
	}
	if (i != wordlistsize) {
		fprintf(stderr, "%s: not enough words in %s between %d "
				"and %d letters long.\n%s: (need %d)\n",
				exename, dictname, WORD_LENGTH_MIN,
				WORD_LENGTH_MAX, exename, wordlistsize);
		exit(EXIT_FAILURE);
	}
}

/* read-only stream open or die */
static FILE *ro_fopen(const char *pathname)
{
	FILE *stream;
	if (!(stream = fopen(pathname, "r"))) {
		perror("fopen");
		fprintf(stderr, "%s: can't open %s for reading\n",
			exename, pathname);
		exit(EXIT_FAILURE);
	}
	return stream;
}

/* read-only fd open or die */
static int ro_open(const char *pathname)
{
	int fd;
	if ((fd = open(pathname, O_RDONLY)) == -1) {
		perror("open");
		fprintf(stderr, "%s: can't open %s for reading\n",
			exename, pathname);
		exit(EXIT_FAILURE);
	}
	return fd;
}

/* read or die, ignore interruptions */
ssize_t xread(int fd, void *buf, size_t count)
{
	ssize_t retval;
	do {
		retval = read(fd, buf, count);
	} while ((retval < 0) && (errno == EINTR));
	if (retval < 0) {
		perror("read");
		exit(EXIT_FAILURE);
	}
	return retval;
}

/* read entire buffer or die */
ssize_t xaread(int fd, void *buf, size_t count)
{
	unsigned char *cbuf = buf;
	int nread = 1, remain;
	for (remain = count; nread && remain; remain -= nread)
		cbuf += (nread = xread(fd, cbuf, remain));
	return count;
}

/* duplicate string or die */
static char *xstrdup(const char *s)
{
	char *d = strdup(s);
	if (!d) {
		fprintf(stderr, "%s: virtual memory exhausted\n", exename);
		exit(EXIT_FAILURE);
	}
	return d;
}


int main(int argc, char *argv[])
{
	int i, rfd;
	char *ptr;

	exename = (ptr = strrchr(argv[0], '/')) ? (ptr+1) : argv[0];
	if (argc != 2) {
		fprintf(stderr, "%s: usage: '%s <path-to-dictionary>'\n",
			exename, exename);
		exit(EXIT_FAILURE);
	}
	rfd = ro_open("/dev/random");
	load_words(argv[1]);

	for (i=NUM_OUTPUT_WORDS; i; --i) {
		const char *word;
		uint32_t rbits;

		/* get 32 random bits */
		xaread(rfd, &rbits, sizeof rbits);

		/* choose + print random word and number */
		word = wordlist[rbits & DICT_RANDOM_MASK];
		assert(DICT_RANDOM_BITS + 3 <= 32);
		rbits >>= DICT_RANDOM_BITS;
		printf("%d%s%c", (rbits & 7) + 1, word, (i == 1) ? '\n' : ' ');
	}
	return 0;
}


[Index of Archives]     [Kernel]     [Linux Crypto]     [Gnu Crypto]     [Gnu Classpath]     [Netfilter]     [Bugtraq]
  Powered by Linux