From 8818cd533fef05326e59ebf3962c7f3f41fb3c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Groenvall?= Date: Fri, 9 Jun 1995 09:55:57 +0000 Subject: [PATCH] Initial revision git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@12 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/des/des.h | 83 +++++++++++++++++++++++++++++++++ lib/des/rnd_keys.c | 114 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 lib/des/des.h create mode 100644 lib/des/rnd_keys.c diff --git a/lib/des/des.h b/lib/des/des.h new file mode 100644 index 000000000..f6b96a833 --- /dev/null +++ b/lib/des/des.h @@ -0,0 +1,83 @@ +/* des.h */ +/* Copyright (C) 1993 Eric Young - see README for more details */ +#ifndef DES_DEFS +#define DES_DEFS + +#include +#include + +typedef unsigned char des_cblock[8]; +typedef struct des_ks_struct + { + union { + des_cblock _; + /* make sure things are correct size on machines with + * 8 byte longs */ + u_int32_t pad[2]; + } ks; +#define _ ks._ + } des_key_schedule[16]; + +#define DES_KEY_SZ (sizeof(des_cblock)) +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define DES_CBC_MODE 0 +#define DES_PCBC_MODE 1 + +#if !defined(NCOMPAT) +#define C_Block des_cblock +#define Key_schedule des_key_schedule +#define ENCRYPT DES_ENCRYPT +#define DECRYPT DES_DECRYPT +#define KEY_SZ DES_KEY_SZ +#define string_to_key des_string_to_key +#define read_pw_string des_read_pw_string +#define random_key des_random_key +#define pcbc_encrypt des_pcbc_encrypt +#define set_key des_set_key +#define key_sched des_key_sched +#define ecb_encrypt des_ecb_encrypt +#define cbc_encrypt des_cbc_encrypt +#define cbc_cksum des_cbc_cksum +#define quad_cksum des_quad_cksum + +/* For compatibility with the MIT lib - eay 20/05/92 */ +typedef struct des_ks_struct bit_64; +#endif + +extern int des_check_key; /* defaults to false */ +extern int des_rw_mode; /* defaults to DES_PCBC_MODE */ + +extern int des_3ecb_encrypt __P((des_cblock *input,des_cblock *output,des_key_schedule ks1,des_key_schedule ks2,int encrypt)); +extern int des_3cbc_encrypt __P((des_cblock *input,des_cblock *output,long length,des_key_schedule sk1,des_key_schedule sk2,des_cblock *ivec1,des_cblock *ivec2,int encrypt)); +extern u_int32_t des_cbc_cksum __P((des_cblock *input,des_cblock *output,long length,des_key_schedule schedule,des_cblock *ivec)); +extern int des_cbc_encrypt __P((des_cblock *input,des_cblock *output,long length,des_key_schedule schedule,des_cblock *ivec,int encrypt)); +extern int des_cfb_encrypt __P((unsigned char *in,unsigned char *out,int numbits,long length,des_key_schedule schedule,des_cblock *ivec,int encrypt)); +extern int des_ecb_encrypt __P((des_cblock *input,des_cblock *output,des_key_schedule ks,int encrypt)); +extern int des_encrypt __P((u_int32_t *input,u_int32_t *output,des_key_schedule ks, int encrypt)); +extern int des_enc_read __P((int fd,char *buf,int len,des_key_schedule sched,des_cblock *iv)); +extern int des_enc_write __P((int fd,char *buf,int len,des_key_schedule sched,des_cblock *iv)); +extern int des_ofb_encrypt __P((unsigned char *in,unsigned char *out,int numbits,long length,des_key_schedule schedule,des_cblock *ivec)); +extern int des_pcbc_encrypt __P((des_cblock *input,des_cblock *output,long length,des_key_schedule schedule,des_cblock *ivec,int encrypt)); + +extern void des_set_odd_parity __P((des_cblock *key)); +extern int des_is_weak_key __P((des_cblock *key)); +extern int des_set_key __P((des_cblock *key,des_key_schedule schedule)); +extern int des_key_sched __P((des_cblock *key,des_key_schedule schedule)); +extern void des_fixup_key_parity __P((des_cblock *key)); + +extern int des_string_to_key __P((char *str,des_cblock *key)); +extern int des_string_to_2keys __P((char *str,des_cblock *key1,des_cblock *key2)); + +extern void des_set_random_generator_seed __P((des_cblock *seed)); +extern int des_new_random_key __P((des_cblock *key)); +extern void des_init_random_number_generator __P((des_cblock *seed)); +extern int des_random_key __P((des_cblock ret)); +extern int des_read_password __P((des_cblock *key,char *prompt,int verify)); +extern int des_read_2passwords __P((des_cblock *key1,des_cblock *key2,char *prompt,int verify)); +extern int des_read_pw_string __P((char *buf,int length,char *prompt,int verify)); + +extern u_int32_t des_quad_cksum __P((des_cblock *input,des_cblock *output,long length,int out_count,des_cblock *seed)); + +#endif /* DES_DEFS */ diff --git a/lib/des/rnd_keys.c b/lib/des/rnd_keys.c new file mode 100644 index 000000000..10ae28330 --- /dev/null +++ b/lib/des/rnd_keys.c @@ -0,0 +1,114 @@ +/* rnd_keys.c */ +/* Copyright (C) 1993 Eric Young - see COPYING for more details */ +#include "des_locl.h" +#include + +#include + +#include +#include +#include + +/* + * Create a sequence of random 64 bit blocks. + * The sequence is indexed with a long long and + * based on an initial des key used as a seed. + */ +static des_key_schedule sequence_seed; +static u_int32_t sequence_index[2]; + +#define zero_long_long(ll) do { ll[0] = ll[1] = 0; } while (0) + +#define incr_long_long(ll) do { if (++ll[0] == 0) ++ll[1]; } while (0) + +#define des_set_sequence_number(ll) \ +do { \ + memcpy((char *)sequence_index, (ll), sizeof(sequence_index)); \ + } while (0) + +#define des_generate_random_block(ret) \ +do { \ + des_ecb_encrypt((des_cblock *) sequence_index, (ret), sequence_seed, DES_ENCRYPT); \ + incr_long_long(sequence_index); \ + } while (0) + +void +des_set_random_generator_seed(des_cblock *seed) +{ + des_key_sched(seed, sequence_seed); + zero_long_long(sequence_index); +} + +/* + * Generate a sequence of random des keys + * using the random block sequence, fixup + * parity and skip weak keys. + */ +int +des_new_random_key(des_cblock *key) +{ + try_again: + des_generate_random_block(key); + /* random key must have odd parity and not be weak */ + des_set_odd_parity(key); + if (des_is_weak_key(key)) + goto try_again; + return(0); +} + +/* + * des_init_random_number_generator: + * + * This routine takes a secret key possibly shared by a number + * of servers and uses it to generate a random number stream that is + * not shared by any of the other servers. It does this by using the current + * process id, host id, and the current time to the nearest second. The + * resulting stream seed is not useful information for cracking the secret + * key. Moreover, this routine keeps no copy of the secret key. + * + */ +void +des_init_random_number_generator(des_cblock *seed) +{ + struct timeval now; + static long uniq[2]; + des_cblock new_key; + long gethostid(void); + + gettimeofday(&now, (struct timezone *)0); + if (!uniq[0]) + { + struct hostent *hent; + char hostname[100]; + gethostname(hostname, sizeof(hostname)); + hent = gethostbyname(hostname); + if (hent != NULL) + bcopy(hent->h_addr_list[0], &uniq[0], sizeof(uniq[0])); + else + uniq[0] = gethostid(); +#ifdef MSDOS + uniq[1] = 1; +#else + uniq[1] = getpid(); +#endif + } + + /* Pick a unique random key from the shared sequence. */ + des_set_random_generator_seed(seed); + des_set_sequence_number((unsigned char *)uniq); + des_new_random_key(&new_key); + + /* Select a new nonshared sequence, */ + des_set_random_generator_seed(&new_key); + + /* and use the current time to pick a key for the new sequence. */ + des_set_sequence_number((unsigned char *)&now); + des_new_random_key(&new_key); + des_set_random_generator_seed(&new_key); +} + +void +des_fixup_key_parity(des_cblock *key) +{ + des_set_odd_parity(key); +}