From a925f039ee382df0f3be434108416bab0d17e8c0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 1 Aug 2008 07:08:51 +0200 Subject: heimdal: update to lorikeet-heimdal rev 801 metze (This used to be commit d6c54a66fb23c784ef221a3c1cf766b72bdb5a0b) --- source4/heimdal/lib/hcrypto/aes.c | 0 source4/heimdal/lib/hcrypto/aes.h | 10 +- source4/heimdal/lib/hcrypto/bn.c | 6 +- source4/heimdal/lib/hcrypto/camellia-ntt.c | 22 +- source4/heimdal/lib/hcrypto/camellia-ntt.h | 6 +- source4/heimdal/lib/hcrypto/camellia.h | 8 +- source4/heimdal/lib/hcrypto/des.c | 302 +++++++++++++--- source4/heimdal/lib/hcrypto/des.h | 78 ++-- source4/heimdal/lib/hcrypto/evp.c | 31 +- source4/heimdal/lib/hcrypto/evp.h | 26 +- source4/heimdal/lib/hcrypto/imath/LICENSE | 2 +- source4/heimdal/lib/hcrypto/pkcs12.c | 24 +- source4/heimdal/lib/hcrypto/pkcs5.c | 18 +- source4/heimdal/lib/hcrypto/rand-egd.c | 4 +- source4/heimdal/lib/hcrypto/rand-fortuna.c | 15 +- source4/heimdal/lib/hcrypto/rand-unix.c | 6 +- source4/heimdal/lib/hcrypto/rand.c | 166 ++++++++- source4/heimdal/lib/hcrypto/rc2.c | 0 source4/heimdal/lib/hcrypto/rc2.h | 0 source4/heimdal/lib/hcrypto/rc4.c | 0 source4/heimdal/lib/hcrypto/rijndael-alg-fst.c | 0 source4/heimdal/lib/hcrypto/rijndael-alg-fst.h | 0 source4/heimdal/lib/hcrypto/rnd_keys.c | 471 +++---------------------- source4/heimdal/lib/hcrypto/ui.c | 8 +- 24 files changed, 654 insertions(+), 549 deletions(-) mode change 100755 => 100644 source4/heimdal/lib/hcrypto/aes.c mode change 100755 => 100644 source4/heimdal/lib/hcrypto/aes.h mode change 100755 => 100644 source4/heimdal/lib/hcrypto/rc2.c mode change 100755 => 100644 source4/heimdal/lib/hcrypto/rc2.h mode change 100755 => 100644 source4/heimdal/lib/hcrypto/rc4.c mode change 100755 => 100644 source4/heimdal/lib/hcrypto/rijndael-alg-fst.c mode change 100755 => 100644 source4/heimdal/lib/hcrypto/rijndael-alg-fst.h (limited to 'source4/heimdal/lib/hcrypto') diff --git a/source4/heimdal/lib/hcrypto/aes.c b/source4/heimdal/lib/hcrypto/aes.c old mode 100755 new mode 100644 diff --git a/source4/heimdal/lib/hcrypto/aes.h b/source4/heimdal/lib/hcrypto/aes.h old mode 100755 new mode 100644 index e91d8e73e1..eeba5c9e51 --- a/source4/heimdal/lib/hcrypto/aes.h +++ b/source4/heimdal/lib/hcrypto/aes.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: aes.h 17450 2006-05-05 11:11:43Z lha $ */ +/* $Id: aes.h 22958 2008-04-11 11:33:22Z lha $ */ #ifndef HEIM_AES_H #define HEIM_AES_H 1 @@ -58,6 +58,10 @@ typedef struct aes_key { int rounds; } AES_KEY; +#ifdef __cplusplus +extern "C" { +#endif + int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *); int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *); @@ -68,4 +72,8 @@ void AES_cbc_encrypt(const unsigned char *, unsigned char *, const unsigned long, const AES_KEY *, unsigned char *, int); +#ifdef __cplusplus +} +#endif + #endif /* HEIM_AES_H */ diff --git a/source4/heimdal/lib/hcrypto/bn.c b/source4/heimdal/lib/hcrypto/bn.c index 6076478bbb..1f8c1d5471 100644 --- a/source4/heimdal/lib/hcrypto/bn.c +++ b/source4/heimdal/lib/hcrypto/bn.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: bn.c 22261 2007-12-09 06:24:18Z lha $"); +RCSID("$Id: bn.c 22850 2008-04-07 18:49:01Z lha $"); #include #include @@ -297,13 +297,13 @@ BN_set_word(BIGNUM *bn, unsigned long num) for (num2 = num, i = 0; num2 > 0; i++) num2 = num2 >> 8; - len = i - 1; + len = i; for (; i > 0; i--) { p[i - 1] = (num & 0xff); num = num >> 8; } - bn = BN_bin2bn(p, len + 1, bn); + bn = BN_bin2bn(p, len, bn); return bn != NULL; } diff --git a/source4/heimdal/lib/hcrypto/camellia-ntt.c b/source4/heimdal/lib/hcrypto/camellia-ntt.c index c32c406baa..80fc49aef9 100644 --- a/source4/heimdal/lib/hcrypto/camellia-ntt.c +++ b/source4/heimdal/lib/hcrypto/camellia-ntt.c @@ -23,14 +23,12 @@ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html */ + #include #include -#include "camellia.h" - -/* u32 must be 32bit word */ -typedef unsigned int u32; -typedef unsigned char u8; +#include +#include "camellia-ntt.h" /* key constants */ @@ -444,7 +442,7 @@ static const u32 camellia_sp4404[256] = { #define subl(x) subL[(x)] #define subr(x) subR[(x)] -void camellia_setup128(const unsigned char *key, u32 *subkey) +static void camellia_setup128(const unsigned char *key, u32 *subkey) { u32 kll, klr, krl, krr; u32 il, ir, t0, t1, w0, w1; @@ -655,7 +653,7 @@ void camellia_setup128(const unsigned char *key, u32 *subkey) return; } -void camellia_setup256(const unsigned char *key, u32 *subkey) +static void camellia_setup256(const unsigned char *key, u32 *subkey) { u32 kll,klr,krl,krr; /* left half of key */ u32 krll,krlr,krrl,krrr; /* right half of key */ @@ -941,7 +939,7 @@ void camellia_setup256(const unsigned char *key, u32 *subkey) return; } -void camellia_setup192(const unsigned char *key, u32 *subkey) +static void camellia_setup192(const unsigned char *key, u32 *subkey) { unsigned char kk[32]; u32 krll, krlr, krrl,krrr; @@ -963,7 +961,7 @@ void camellia_setup192(const unsigned char *key, u32 *subkey) * * "io" must be 4byte aligned and big-endian data. */ -void camellia_encrypt128(const u32 *subkey, u32 *io) +static void camellia_encrypt128(const u32 *subkey, u32 *io) { u32 il, ir, t0, t1; @@ -1053,7 +1051,7 @@ void camellia_encrypt128(const u32 *subkey, u32 *io) return; } -void camellia_decrypt128(const u32 *subkey, u32 *io) +static void camellia_decrypt128(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ @@ -1146,7 +1144,7 @@ void camellia_decrypt128(const u32 *subkey, u32 *io) /** * stuff for 192 and 256bit encryption/decryption */ -void camellia_encrypt256(const u32 *subkey, u32 *io) +static void camellia_encrypt256(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ @@ -1260,7 +1258,7 @@ void camellia_encrypt256(const u32 *subkey, u32 *io) return; } -void camellia_decrypt256(const u32 *subkey, u32 *io) +static void camellia_decrypt256(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ diff --git a/source4/heimdal/lib/hcrypto/camellia-ntt.h b/source4/heimdal/lib/hcrypto/camellia-ntt.h index 740ed8bfd9..8356e3b31e 100644 --- a/source4/heimdal/lib/hcrypto/camellia-ntt.h +++ b/source4/heimdal/lib/hcrypto/camellia-ntt.h @@ -29,7 +29,11 @@ extern "C" { #define CAMELLIA_TABLE_BYTE_LEN 272 #define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) -typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; +/* u32 must be 32bit word */ +typedef uint32_t u32; +typedef unsigned char u8; + +typedef u32 KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; void Camellia_Ekeygen(const int keyBitLength, diff --git a/source4/heimdal/lib/hcrypto/camellia.h b/source4/heimdal/lib/hcrypto/camellia.h index 3b21934b66..f736f88b1e 100644 --- a/source4/heimdal/lib/hcrypto/camellia.h +++ b/source4/heimdal/lib/hcrypto/camellia.h @@ -36,9 +36,6 @@ #ifndef HEIM_CAMELLIA_H #define HEIM_CAMELLIA_H 1 -#include -#include "camellia-ntt.h" - /* symbol renaming */ #define CAMELLIA_set_key hc_CAMELLIA_set_encrypt_key #define CAMELLIA_encrypt hc_CAMELLIA_encrypt @@ -50,14 +47,15 @@ */ #define CAMELLIA_BLOCK_SIZE 16 -#define CAMELLIA_MAXNR 14 +#define CAMELLIA_TABLE_BYTE_LEN 272 +#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) #define CAMELLIA_ENCRYPT 1 #define CAMELLIA_DECRYPT 0 typedef struct camellia_key { unsigned int bits; - KEY_TABLE_TYPE key; + uint32_t key[CAMELLIA_TABLE_WORD_LEN]; } CAMELLIA_KEY; int CAMELLIA_set_key(const unsigned char *, const int, CAMELLIA_KEY *); diff --git a/source4/heimdal/lib/hcrypto/des.c b/source4/heimdal/lib/hcrypto/des.c index a4444a8a7c..9e533dd708 100644 --- a/source4/heimdal/lib/hcrypto/des.c +++ b/source4/heimdal/lib/hcrypto/des.c @@ -31,7 +31,46 @@ * SUCH DAMAGE. */ -/* +/** + * @page page_des DES - Data Encryption Standard crypto interface + * + * See the library functions here: @ref hcrypto_des + * + * DES was created by IBM, modififed by NSA and then adopted by NBS + * (now NIST) and published ad FIPS PUB 46 (updated by FIPS 46-1). + * + * Since the 19th May 2005 DES was withdrawn by NIST and should no + * longer be used. See @ref page_evp for replacement encryption + * algorithms and interfaces. + * + * Read more the iteresting history of DES on Wikipedia + * http://www.wikipedia.org/wiki/Data_Encryption_Standard . + * + * @section des_keygen DES key generation + * + * To generate a DES key safely you have to use the code-snippet + * below. This is because the DES_random_key() can fail with an + * abort() in case of and failure to start the random generator. + * + * There is a replacement function DES_new_random_key(), however that + * function does not exists in OpenSSL. + * + * @code + * DES_cblock key; + * do { + * if (RAND_rand(&key, sizeof(key)) != 1) + * goto failure; + * DES_set_odd_parity(key); + * } while (DES_is_weak_key(&key)); + * @endcode + * + * @section des_impl DES implementation history + * + * There was no complete BSD licensed, fast, GPL compatible + * implementation of DES, so Love wrote the part that was missing, + * fast key schedule setup and adapted the interface to the orignal + * libdes. + * * The document that got me started for real was "Efficient * Implementation of the Data Encryption Standard" by Dag Arne Osvik. * I never got to the PC1 transformation was working, instead I used @@ -45,9 +84,11 @@ #ifdef HAVE_CONFIG_H #include -RCSID("$Id: des.c 17211 2006-04-24 14:26:19Z lha $"); +RCSID("$Id: des.c 23117 2008-04-28 10:29:36Z lha $"); #endif +#define HC_DEPRECATED + #include #include #include @@ -70,17 +111,39 @@ static void FP(uint32_t [2]); x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \ } -/* +/** + * Set the parity of the key block, used to generate a des key from a + * random key. See @ref des_keygen. * + * @param key key to fixup the parity for. + * @ingroup hcrypto_des */ -int +void DES_set_odd_parity(DES_cblock *key) { - int i; + unsigned int i; for (i = 0; i < DES_CBLOCK_LEN; i++) (*key)[i] = odd_parity[(*key)[i]]; - return 0; +} + +/** + * Check if the key have correct parity. + * + * @param key key to check the parity. + * @return 1 on success, 0 on failure. + * @ingroup hcrypto_des + */ + +int HC_DEPRECATED +DES_check_key_parity(DES_cblock *key) +{ + unsigned int i; + + for (i = 0; i < DES_CBLOCK_LEN; i++) + if ((*key)[i] != odd_parity[(*key)[i]]) + return 0; + return 1; } /* @@ -107,6 +170,16 @@ static DES_cblock weak_keys[] = { {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1} }; +/** + * Checks if the key is any of the weaks keys that makes DES attacks + * trival. + * + * @param key key to check. + * + * @return 1 if the key is weak, 0 otherwise. + * @ingroup hcrypto_des + */ + int DES_is_weak_key(DES_cblock *key) { @@ -119,13 +192,38 @@ DES_is_weak_key(DES_cblock *key) return 0; } +/** + * Setup a des key schedule from a key. Deprecated function, use + * DES_set_key_unchecked() or DES_set_key_checked() instead. + * + * @param key a key to initialize the key schedule with. + * @param ks a key schedule to initialize. + * + * @return 0 on success + * @ingroup hcrypto_des + */ -/* +int HC_DEPRECATED +DES_set_key(DES_cblock *key, DES_key_schedule *ks) +{ + return DES_set_key_checked(key, ks); +} + +/** + * Setup a des key schedule from a key. The key is no longer needed + * after this transaction and can cleared. * + * Does NOT check that the key is weak for or have wrong parity. + * + * @param key a key to initialize the key schedule with. + * @param ks a key schedule to initialize. + * + * @return 0 on success + * @ingroup hcrypto_des */ int -DES_set_key(DES_cblock *key, DES_key_schedule *ks) +DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks) { uint32_t t1, t2; uint32_t c, d; @@ -184,28 +282,46 @@ DES_set_key(DES_cblock *key, DES_key_schedule *ks) return 0; } -/* +/** + * Just like DES_set_key_unchecked() except checking that the key is + * not weak for or have correct parity. + * + * @param key a key to initialize the key schedule with. + * @param ks a key schedule to initialize. * + * @return 0 on success, -1 on invalid parity, -2 on weak key. + * @ingroup hcrypto_des */ int DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks) { + if (!DES_check_key_parity(key)) { + memset(ks, 0, sizeof(*ks)); + return -1; + } if (DES_is_weak_key(key)) { memset(ks, 0, sizeof(*ks)); - return 1; + return -2; } - return DES_set_key(key, ks); + return DES_set_key_unchecked(key, ks); } -/* - * Compatibility function for eay libdes +/** + * Compatibility function for eay libdes, works just like + * DES_set_key_checked(). + * + * @param key a key to initialize the key schedule with. + * @param ks a key schedule to initialize. + * + * @return 0 on success, -1 on invalid parity, -2 on weak key. + * @ingroup hcrypto_des */ int DES_key_sched(DES_cblock *key, DES_key_schedule *ks) { - return DES_set_key(key, ks); + return DES_set_key_checked(key, ks); } /* @@ -238,39 +354,63 @@ store(const uint32_t v[2], unsigned char *b) b[7] = (v[1] >> 0) & 0xff; } -/* +/** + * Encrypt/decrypt a block using DES. Also called ECB mode + * + * @param u data to encrypt + * @param ks key schedule to use + * @param encp if non zero, encrypt. if zero, decrypt. * + * @ingroup hcrypto_des */ void -DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int forward_encrypt) +DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp) { IP(u); - desx(u, ks, forward_encrypt); + desx(u, ks, encp); FP(u); } -/* +/** + * Encrypt/decrypt a block using DES. * + * @param input data to encrypt + * @param output data to encrypt + * @param ks key schedule to use + * @param encp if non zero, encrypt. if zero, decrypt. + * + * @ingroup hcrypto_des */ void DES_ecb_encrypt(DES_cblock *input, DES_cblock *output, - DES_key_schedule *ks, int forward_encrypt) + DES_key_schedule *ks, int encp) { uint32_t u[2]; load(*input, u); - DES_encrypt(u, ks, forward_encrypt); + DES_encrypt(u, ks, encp); store(u, *output); } -/* +/** + * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc). * + * The IV must always be diffrent for diffrent input data blocks. + * + * @param in data to encrypt + * @param out data to encrypt + * @param length length of data + * @param ks key schedule to use + * @param iv initial vector to use + * @param encp if non zero, encrypt. if zero, decrypt. + * + * @ingroup hcrypto_des */ void DES_cbc_encrypt(const void *in, void *out, long length, - DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt) + DES_key_schedule *ks, DES_cblock *iv, int encp) { const unsigned char *input = in; unsigned char *output = out; @@ -279,7 +419,7 @@ DES_cbc_encrypt(const void *in, void *out, long length, load(*iv, uiv); - if (forward_encrypt) { + if (encp) { while (length >= DES_CBLOCK_LEN) { load(input, u); u[0] ^= uiv[0]; u[1] ^= uiv[1]; @@ -327,13 +467,26 @@ DES_cbc_encrypt(const void *in, void *out, long length, uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; } -/* +/** + * Encrypt/decrypt a block using DES in Propagating Cipher Block + * Chaining mode. This mode is only used for Kerberos 4, and it should + * stay that way. + * + * The IV must always be diffrent for diffrent input data blocks. * + * @param in data to encrypt + * @param out data to encrypt + * @param length length of data + * @param ks key schedule to use + * @param iv initial vector to use + * @param encp if non zero, encrypt. if zero, decrypt. + * + * @ingroup hcrypto_des */ void DES_pcbc_encrypt(const void *in, void *out, long length, - DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt) + DES_key_schedule *ks, DES_cblock *iv, int encp) { const unsigned char *input = in; unsigned char *output = out; @@ -342,7 +495,7 @@ DES_pcbc_encrypt(const void *in, void *out, long length, load(*iv, uiv); - if (forward_encrypt) { + if (encp) { uint32_t t[2]; while (length >= DES_CBLOCK_LEN) { load(input, u); @@ -397,10 +550,10 @@ DES_pcbc_encrypt(const void *in, void *out, long length, static void _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2, - DES_key_schedule *ks3, int forward_encrypt) + DES_key_schedule *ks3, int encp) { IP(u); - if (forward_encrypt) { + if (encp) { desx(u, ks1, 1); /* IP + FP cancel out each other */ desx(u, ks2, 0); desx(u, ks3, 1); @@ -412,8 +565,18 @@ _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2, FP(u); } -/* +/** + * Encrypt/decrypt a block using triple DES using EDE mode, + * encrypt/decrypt/encrypt. + * + * @param input data to encrypt + * @param output data to encrypt + * @param ks1 key schedule to use + * @param ks2 key schedule to use + * @param ks3 key schedule to use + * @param encp if non zero, encrypt. if zero, decrypt. * + * @ingroup hcrypto_des */ void @@ -422,24 +585,37 @@ DES_ecb3_encrypt(DES_cblock *input, DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, - int forward_encrypt) + int encp) { uint32_t u[2]; load(*input, u); - _des3_encrypt(u, ks1, ks2, ks3, forward_encrypt); + _des3_encrypt(u, ks1, ks2, ks3, encp); store(u, *output); return; } -/* +/** + * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc). + * + * The IV must always be diffrent for diffrent input data blocks. * + * @param in data to encrypt + * @param out data to encrypt + * @param length length of data + * @param ks1 key schedule to use + * @param ks2 key schedule to use + * @param ks3 key schedule to use + * @param iv initial vector to use + * @param encp if non zero, encrypt. if zero, decrypt. + * + * @ingroup hcrypto_des */ void DES_ede3_cbc_encrypt(const void *in, void *out, long length, DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, - DES_cblock *iv, int forward_encrypt) + DES_cblock *iv, int encp) { const unsigned char *input = in; unsigned char *output = out; @@ -448,7 +624,7 @@ DES_ede3_cbc_encrypt(const void *in, void *out, load(*iv, uiv); - if (forward_encrypt) { + if (encp) { while (length >= DES_CBLOCK_LEN) { load(input, u); u[0] ^= uiv[0]; u[1] ^= uiv[1]; @@ -497,14 +673,27 @@ DES_ede3_cbc_encrypt(const void *in, void *out, uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; } -/* +/** + * Encrypt/decrypt using DES in cipher feedback mode with 64 bit + * feedback. + * + * The IV must always be diffrent for diffrent input data blocks. + * + * @param in data to encrypt + * @param out data to encrypt + * @param length length of data + * @param ks key schedule to use + * @param iv initial vector to use + * @param num offset into in cipher block encryption/decryption stop last time. + * @param encp if non zero, encrypt. if zero, decrypt. * + * @ingroup hcrypto_des */ void DES_cfb64_encrypt(const void *in, void *out, long length, DES_key_schedule *ks, DES_cblock *iv, - int *num, int forward_encrypt) + int *num, int encp) { const unsigned char *input = in; unsigned char *output = out; @@ -515,7 +704,7 @@ DES_cfb64_encrypt(const void *in, void *out, assert(*num >= 0 && *num < DES_CBLOCK_LEN); - if (forward_encrypt) { + if (encp) { int i = *num; while (length > 0) { @@ -562,8 +751,19 @@ DES_cfb64_encrypt(const void *in, void *out, } } -/* +/** + * Crete a checksum using DES in CBC encryption mode. This mode is + * only used for Kerberos 4, and it should stay that way. + * + * The IV must always be diffrent for diffrent input data blocks. + * + * @param in data to checksum + * @param output the checksum + * @param length length of data + * @param ks key schedule to use + * @param iv initial vector to use * + * @ingroup hcrypto_des */ uint32_t @@ -616,6 +816,16 @@ bitswap8(unsigned char b) return r; } +/** + * Convert a string to a DES key. Use something like + * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords. + * + * @param str The string to convert to a key + * @param key the resulting key + * + * @ingroup hcrypto_des + */ + void DES_string_to_key(const char *str, DES_cblock *key) { @@ -646,8 +856,16 @@ DES_string_to_key(const char *str, DES_cblock *key) k[7] ^= 0xF0; } -/* +/** + * Read password from prompt and create a DES key. Internal uses + * DES_string_to_key(). Really, go use a really string2key function + * like PKCS5_PBKDF2_HMAC_SHA1(). + * + * @param key key to convert to + * @param prompt prompt to display user + * @param verify prompt twice. * + * @return 1 on success, non 1 on failure. */ int @@ -657,7 +875,7 @@ DES_read_password(DES_cblock *key, char *prompt, int verify) int ret; ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify); - if (ret == 0) + if (ret == 1) DES_string_to_key(buf, key); return ret; } @@ -892,7 +1110,7 @@ FP(uint32_t v[2]) } static void -desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt) +desx(uint32_t block[2], DES_key_schedule *ks, int encp) { uint32_t *keys; uint32_t fval, work, right, left; @@ -901,7 +1119,7 @@ desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt) left = block[0]; right = block[1]; - if (forward_encrypt) { + if (encp) { keys = &ks->ks[0]; for( round = 0; round < 8; round++ ) { diff --git a/source4/heimdal/lib/hcrypto/des.h b/source4/heimdal/lib/hcrypto/des.h index ac8deb8ab8..3c52f59e28 100644 --- a/source4/heimdal/lib/hcrypto/des.h +++ b/source4/heimdal/lib/hcrypto/des.h @@ -31,36 +31,38 @@ * SUCH DAMAGE. */ -/* $Id: des.h 16480 2006-01-08 21:47:29Z lha $ */ +/* $Id: des.h 23148 2008-04-29 05:53:27Z biorn $ */ #ifndef _DESperate_H #define _DESperate_H 1 /* symbol renaming */ -#define DES_set_odd_parity hc_DES_set_odd_parity +#define _DES_ipfp_test _hc_DES_ipfp_test +#define DES_cbc_cksum hc_DES_cbc_cksum +#define DES_cbc_encrypt hc_DES_cbc_encrypt +#define DES_cfb64_encrypt hc_DES_cfb64_encrypt +#define DES_check_key_parity hc_DES_check_key_parity +#define DES_ecb3_encrypt hc_DES_ecb3_encrypt +#define DES_ecb_encrypt hc_DES_ecb_encrypt +#define DES_ede3_cbc_encrypt hc_DES_ede3_cbc_encrypt +#define DES_encrypt hc_DES_encrypt +#define DES_generate_random_block hc_DES_generate_random_block +#define DES_init_random_number_generator hc_DES_init_random_number_generator #define DES_is_weak_key hc_DES_is_weak_key #define DES_key_sched hc_DES_key_sched +#define DES_new_random_key hc_DES_new_random_key +#define DES_pcbc_encrypt hc_DES_pcbc_encrypt +#define DES_rand_data hc_DES_rand_data +#define DES_random_key hc_DES_random_key +#define DES_read_password hc_DES_read_password #define DES_set_key hc_DES_set_key #define DES_set_key_checked hc_DES_set_key_checked +#define DES_set_key_unchecked hc_DES_set_key_unchecked #define DES_set_key_sched hc_DES_set_key_sched -#define DES_new_random_key hc_DES_new_random_key -#define DES_string_to_key hc_DES_string_to_key -#define DES_read_password hc_DES_read_password -#define DES_rand_data hc_DES_rand_data +#define DES_set_odd_parity hc_DES_set_odd_parity #define DES_set_random_generator_seed hc_DES_set_random_generator_seed -#define DES_generate_random_block hc_DES_generate_random_block #define DES_set_sequence_number hc_DES_set_sequence_number -#define DES_init_random_number_generator hc_DES_init_random_number_generator -#define DES_random_key hc_DES_random_key -#define DES_encrypt hc_DES_encrypt -#define DES_ecb_encrypt hc_DES_ecb_encrypt -#define DES_ecb3_encrypt hc_DES_ecb3_encrypt -#define DES_pcbc_encrypt hc_DES_pcbc_encrypt -#define DES_cbc_encrypt hc_DES_cbc_encrypt -#define DES_cbc_cksum hc_DES_cbc_cksum -#define DES_ede3_cbc_encrypt hc_DES_ede3_cbc_encrypt -#define DES_cfb64_encrypt hc_DES_cfb64_encrypt -#define _DES_ipfp_test _hc_DES_ipfp_test +#define DES_string_to_key hc_DES_string_to_key /* * @@ -82,21 +84,35 @@ typedef struct DES_key_schedule * */ -int DES_set_odd_parity(DES_cblock *); +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + +#ifndef HC_DEPRECATED +#define HC_DEPRECATED __attribute__((deprecated)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void DES_set_odd_parity(DES_cblock *); +int DES_check_key_parity(DES_cblock *); int DES_is_weak_key(DES_cblock *); -int DES_set_key(DES_cblock *, DES_key_schedule *); +int HC_DEPRECATED DES_set_key(DES_cblock *, DES_key_schedule *); int DES_set_key_checked(DES_cblock *, DES_key_schedule *); +int DES_set_key_unchecked(DES_cblock *, DES_key_schedule *); int DES_key_sched(DES_cblock *, DES_key_schedule *); -int DES_new_random_key(DES_cblock *); void DES_string_to_key(const char *, DES_cblock *); int DES_read_password(DES_cblock *, char *, int); -void DES_rand_data(void *, int); -void DES_set_random_generator_seed(DES_cblock *); -void DES_generate_random_block(DES_cblock *); -void DES_set_sequence_number(void *); -void DES_init_random_number_generator(DES_cblock *); -void DES_random_key(DES_cblock *); +void HC_DEPRECATED DES_rand_data(void *, int); +void HC_DEPRECATED DES_set_random_generator_seed(DES_cblock *); +void HC_DEPRECATED DES_generate_random_block(DES_cblock *); +void HC_DEPRECATED DES_set_sequence_number(void *); +void HC_DEPRECATED DES_init_random_number_generator(DES_cblock *); +void HC_DEPRECATED DES_random_key(DES_cblock *); +int HC_DEPRECATED DES_new_random_key(DES_cblock *); void DES_encrypt(uint32_t [2], DES_key_schedule *, int); @@ -110,8 +126,8 @@ void DES_cbc_encrypt(const void *, void *, long, void DES_ede3_cbc_encrypt(const void *, void *, long, DES_key_schedule *, DES_key_schedule *, DES_key_schedule *, DES_cblock *, int); -void DES_cfb64_encrypt(const void *, void *, long, - DES_key_schedule *, DES_cblock *, int *, int); +void DES_cfb64_encrypt(const void *, void *, long, + DES_key_schedule *, DES_cblock *, int *, int); uint32_t DES_cbc_cksum(const void *, DES_cblock *, @@ -120,5 +136,9 @@ uint32_t DES_cbc_cksum(const void *, DES_cblock *, void _DES_ipfp_test(void); +#ifdef __cplusplus +} +#endif + #endif /* _DESperate_H */ diff --git a/source4/heimdal/lib/hcrypto/evp.c b/source4/heimdal/lib/hcrypto/evp.c index 788000b054..b4fb8a7f23 100644 --- a/source4/heimdal/lib/hcrypto/evp.c +++ b/source4/heimdal/lib/hcrypto/evp.c @@ -35,7 +35,9 @@ #include #endif -RCSID("$Id: evp.c 22379 2007-12-29 11:13:26Z lha $"); +RCSID("$Id: evp.c 23144 2008-04-29 05:47:16Z lha $"); + +#define HC_DEPRECATED #include #include @@ -79,6 +81,13 @@ struct hc_evp_md { evp_md_cleanup cleanup; }; +struct hc_EVP_MD_CTX { + const EVP_MD *md; + ENGINE *engine; + void *ptr; +}; + + /** * Return the output size of the message digest function. * @@ -135,7 +144,7 @@ EVP_MD_CTX_create(void) * @ingroup hcrypto_evp */ -void +void HC_DEPRECATED EVP_MD_CTX_init(EVP_MD_CTX *ctx) { memset(ctx, 0, sizeof(*ctx)); @@ -166,7 +175,7 @@ EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) * @ingroup hcrypto_evp */ -int +int HC_DEPRECATED EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { if (ctx->md && ctx->md->cleanup) @@ -508,7 +517,6 @@ EVP_md_null(void) } #if 0 -void EVP_MD_CTX_init(EVP_MD_CTX *ctx); int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); int EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s); int EVP_SignFinal(EVP_MD_CTX *, void *, size_t *, EVP_PKEY *); @@ -1050,10 +1058,19 @@ des_ede3_cbc_init(EVP_CIPHER_CTX *ctx, int encp) { struct des_ede3_cbc *k = ctx->cipher_data; + DES_cblock deskey; + + memcpy(&deskey, key, sizeof(deskey)); + DES_set_odd_parity(&deskey); + DES_set_key_unchecked(&deskey, &k->ks[0]); + + memcpy(&deskey, key + 8, sizeof(deskey)); + DES_set_odd_parity(&deskey); + DES_set_key_unchecked(&deskey, &k->ks[1]); - DES_key_sched((DES_cblock *)(key), &k->ks[0]); - DES_key_sched((DES_cblock *)(key + 8), &k->ks[1]); - DES_key_sched((DES_cblock *)(key + 16), &k->ks[2]); + memcpy(&deskey, key + 16, sizeof(deskey)); + DES_set_odd_parity(&deskey); + DES_set_key_unchecked(&deskey, &k->ks[2]); return 1; } diff --git a/source4/heimdal/lib/hcrypto/evp.h b/source4/heimdal/lib/hcrypto/evp.h index 4910ca01b8..c8f8f80f80 100644 --- a/source4/heimdal/lib/hcrypto/evp.h +++ b/source4/heimdal/lib/hcrypto/evp.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: evp.h 21687 2007-07-24 16:29:05Z lha $ */ +/* $Id: evp.h 23141 2008-04-29 05:47:04Z lha $ */ #ifndef HEIM_EVP_H #define HEIM_EVP_H 1 @@ -155,11 +155,17 @@ struct hc_CIPHER_CTX { unsigned char final[EVP_MAX_BLOCK_LENGTH]; }; -struct hc_EVP_MD_CTX { - const EVP_MD *md; - ENGINE *engine; - void *ptr; -}; +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + +#ifndef HC_DEPRECATED +#define HC_DEPRECATED __attribute__((deprecated)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* * Avaible crypto algs @@ -201,9 +207,9 @@ size_t EVP_MD_CTX_block_size(EVP_MD_CTX *); EVP_MD_CTX * EVP_MD_CTX_create(void); -void EVP_MD_CTX_init(EVP_MD_CTX *); +void HC_DEPRECATED EVP_MD_CTX_init(EVP_MD_CTX *); void EVP_MD_CTX_destroy(EVP_MD_CTX *); -int EVP_MD_CTX_cleanup(EVP_MD_CTX *); +int HC_DEPRECATED EVP_MD_CTX_cleanup(EVP_MD_CTX *); int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *); int EVP_DigestUpdate(EVP_MD_CTX *,const void *, size_t); @@ -258,4 +264,8 @@ void OpenSSL_add_all_algorithms(void); void OpenSSL_add_all_algorithms_conf(void); void OpenSSL_add_all_algorithms_noconf(void); +#ifdef __cplusplus +} +#endif + #endif /* HEIM_EVP_H */ diff --git a/source4/heimdal/lib/hcrypto/imath/LICENSE b/source4/heimdal/lib/hcrypto/imath/LICENSE index cecfb11404..53dd364c2b 100644 --- a/source4/heimdal/lib/hcrypto/imath/LICENSE +++ b/source4/heimdal/lib/hcrypto/imath/LICENSE @@ -1,4 +1,4 @@ -IMath is Copyright 2002-2006 Michael J. Fromberger +IMath is Copyright 2002-2007 Michael J. Fromberger You may use it subject to the following Licensing Terms: Permission is hereby granted, free of charge, to any person obtaining diff --git a/source4/heimdal/lib/hcrypto/pkcs12.c b/source4/heimdal/lib/hcrypto/pkcs12.c index b43fe571d6..fcf04a73c1 100644 --- a/source4/heimdal/lib/hcrypto/pkcs12.c +++ b/source4/heimdal/lib/hcrypto/pkcs12.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: pkcs12.c 21155 2007-06-18 21:59:44Z lha $"); +RCSID("$Id: pkcs12.c 23137 2008-04-29 05:46:48Z lha $"); #include #include @@ -55,19 +55,24 @@ PKCS12_key_gen(const void *key, size_t keylen, unsigned char *v, *I, hash[EVP_MAX_MD_SIZE]; unsigned int size, size_I = 0; unsigned char idc = id; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; unsigned char *outp = out; int i, vlen; - EVP_MD_CTX_init(&ctx); + ctx = EVP_MD_CTX_create(); + if (ctx == NULL) + return 0; vlen = EVP_MD_block_size(md); v = malloc(vlen + 1); - if (v == NULL) + if (v == NULL) { + EVP_MD_CTX_destroy(ctx); return 0; + } I = calloc(1, vlen * 2); if (I == NULL) { + EVP_MD_CTX_destroy(ctx); free(v); return 0; } @@ -93,15 +98,16 @@ PKCS12_key_gen(const void *key, size_t keylen, while (1) { BIGNUM *bnB, *bnOne; - if (!EVP_DigestInit_ex(&ctx, md, NULL)) { + if (!EVP_DigestInit_ex(ctx, md, NULL)) { + EVP_MD_CTX_destroy(ctx); free(I); free(v); return 0; } for (i = 0; i < vlen; i++) - EVP_DigestUpdate(&ctx, &idc, 1); - EVP_DigestUpdate(&ctx, I, size_I); - EVP_DigestFinal_ex(&ctx, hash, &size); + EVP_DigestUpdate(ctx, &idc, 1); + EVP_DigestUpdate(ctx, I, size_I); + EVP_DigestFinal_ex(ctx, hash, &size); for (i = 1; i < iteration; i++) EVP_Digest(hash, size, hash, &size, md, NULL); @@ -145,7 +151,7 @@ PKCS12_key_gen(const void *key, size_t keylen, size_I = vlen * 2; } - EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_destroy(ctx); free(I); free(v); diff --git a/source4/heimdal/lib/hcrypto/pkcs5.c b/source4/heimdal/lib/hcrypto/pkcs5.c index 85b8713cba..8a8f948abb 100644 --- a/source4/heimdal/lib/hcrypto/pkcs5.c +++ b/source4/heimdal/lib/hcrypto/pkcs5.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: pkcs5.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id: pkcs5.c 23059 2008-04-18 13:04:08Z lha $"); #ifdef KRB5 #include @@ -49,6 +49,22 @@ RCSID("$Id: pkcs5.c 17445 2006-05-05 10:37:46Z lha $"); #include +/** + * As descriped in PKCS5, convert a password, salt, and iteration counter into a crypto key. + * + * @param password Password. + * @param password_len Length of password. + * @param salt Salt + * @param salt_len Length of salt. + * @param iter iteration counter. + * @param keylen the output key length. + * @param key the output key. + * + * @return 1 on success, non 1 on failure. + * + * @ingroup hcrypto_misc + */ + int PKCS5_PBKDF2_HMAC_SHA1(const void * password, size_t password_len, const void * salt, size_t salt_len, diff --git a/source4/heimdal/lib/hcrypto/rand-egd.c b/source4/heimdal/lib/hcrypto/rand-egd.c index 497a3ab5f8..c1f306bcc3 100644 --- a/source4/heimdal/lib/hcrypto/rand-egd.c +++ b/source4/heimdal/lib/hcrypto/rand-egd.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: rand-egd.c 21156 2007-06-18 22:00:59Z lha $"); +RCSID("$Id: rand-egd.c 23461 2008-07-27 12:14:20Z lha $"); #include #ifdef HAVE_SYS_UN_H @@ -76,6 +76,8 @@ connect_egd(const char *path) if (fd < 0) return -1; + rk_cloexec(fd); + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { close(fd); return -1; diff --git a/source4/heimdal/lib/hcrypto/rand-fortuna.c b/source4/heimdal/lib/hcrypto/rand-fortuna.c index 1d47ed49cc..da59a433b1 100644 --- a/source4/heimdal/lib/hcrypto/rand-fortuna.c +++ b/source4/heimdal/lib/hcrypto/rand-fortuna.c @@ -33,7 +33,7 @@ #include #endif -RCSID("$Id: rand-fortuna.c 21196 2007-06-20 05:08:58Z lha $"); +RCSID("$Id: rand-fortuna.c 23463 2008-07-27 12:15:06Z lha $"); #include #include @@ -118,6 +118,7 @@ struct fortuna_state unsigned pool0_bytes; unsigned rnd_pos; int tricks_done; + pid_t pid; }; typedef struct fortuna_state FState; @@ -175,6 +176,7 @@ init_state(FState * st) memset(st, 0, sizeof(*st)); for (i = 0; i < NUM_POOLS; i++) md_init(&st->pool[i]); + st->pid = getpid(); } /* @@ -276,6 +278,9 @@ reseed(FState * st) /* add old key into mix too */ md_update(&key_md, st->key, BLOCK); + /* add pid to make output diverse after fork() */ + md_update(&key_md, (const unsigned char *)&st->pid, sizeof(st->pid)); + /* now we have new key */ md_result(&key_md, st->key); @@ -384,6 +389,7 @@ extract_data(FState * st, unsigned count, unsigned char *dst) { unsigned n; unsigned block_nr = 0; + pid_t pid = getpid(); /* Should we reseed? */ if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0) @@ -394,6 +400,12 @@ extract_data(FState * st, unsigned count, unsigned char *dst) if (!st->tricks_done) startup_tricks(st); + /* If we forked, force a reseed again */ + if (pid != st->pid) { + st->pid = pid; + reseed(st); + } + while (count > 0) { /* produce bytes */ @@ -493,6 +505,7 @@ fortuna_reseed(void) fd = open("/etc/shadow", O_RDONLY, 0); if (fd >= 0) { ssize_t n; + rk_cloexec(fd); /* add_entropy will hash the buf */ while ((n = read(fd, (char *)u.shad, sizeof(u.shad))) > 0) add_entropy(&main_state, u.shad, sizeof(u.shad)); diff --git a/source4/heimdal/lib/hcrypto/rand-unix.c b/source4/heimdal/lib/hcrypto/rand-unix.c index 354492fb3d..5fb099d724 100644 --- a/source4/heimdal/lib/hcrypto/rand-unix.c +++ b/source4/heimdal/lib/hcrypto/rand-unix.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: rand-unix.c 20028 2007-01-21 09:54:56Z lha $"); +RCSID("$Id: rand-unix.c 23462 2008-07-27 12:14:42Z lha $"); #include #include @@ -63,8 +63,10 @@ get_device_fd(int flags) for(p = rnd_devices; *p; p++) { int fd = open(*p, flags | O_NDELAY); - if(fd >= 0) + if(fd >= 0) { + rk_cloexec(fd); return fd; + } } return -1; } diff --git a/source4/heimdal/lib/hcrypto/rand.c b/source4/heimdal/lib/hcrypto/rand.c index 79dd39eb76..1561f2ad39 100644 --- a/source4/heimdal/lib/hcrypto/rand.c +++ b/source4/heimdal/lib/hcrypto/rand.c @@ -35,7 +35,7 @@ #include #endif -RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $"); +RCSID("$Id: rand.c 23464 2008-07-27 12:15:21Z lha $"); #include #include @@ -48,8 +48,14 @@ RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $"); #define O_BINARY 0 #endif +/** + * @page page_rand RAND - random number + * + * See the library functions here: @ref hcrypto_rand + */ const static RAND_METHOD *selected_meth = NULL; +static ENGINE *selected_engine = NULL; static void init_method(void) @@ -59,6 +65,16 @@ init_method(void) selected_meth = &hc_rand_fortuna_method; } +/** + * Seed that random number generator. Secret material can securely be + * feed into the function, they will never be returned. + * + * @param indata seed data + * @param size length seed data + * + * @ingroup hcrypto_rand + */ + void RAND_seed(const void *indata, size_t size) { @@ -66,6 +82,16 @@ RAND_seed(const void *indata, size_t size) (*selected_meth->seed)(indata, size); } +/** + * Get a random block from the random generator, can be used for key material. + * + * @param outdata random data + * @param size length random data + * + * @return 1 on success, 0 on failure. + * + * @ingroup hcrypto_rand + */ int RAND_bytes(void *outdata, size_t size) { @@ -73,13 +99,39 @@ RAND_bytes(void *outdata, size_t size) return (*selected_meth->bytes)(outdata, size); } +/** + * Reset and free memory used by the random generator. + * + * @ingroup hcrypto_rand + */ + void RAND_cleanup(void) { - init_method(); - (*selected_meth->cleanup)(); + const RAND_METHOD *meth = selected_meth; + ENGINE *engine = selected_engine; + + selected_meth = NULL; + selected_engine = NULL; + + if (meth) + (*meth->cleanup)(); + if (engine) + ENGINE_finish(engine); } +/** + * Seed that random number generator. Secret material can securely be + * feed into the function, they will never be returned. + * + * @param indata the input data. + * @param size size of in data. + * @param entropi entropi in data. + * + * + * @ingroup hcrypto_rand + */ + void RAND_add(const void *indata, size_t size, double entropi) { @@ -87,6 +139,17 @@ RAND_add(const void *indata, size_t size, double entropi) (*selected_meth->add)(indata, size, entropi); } +/** + * Get a random block from the random generator, should NOT be used for key material. + * + * @param outdata random data + * @param size length random data + * + * @return 1 on success, 0 on failure. + * + * @ingroup hcrypto_rand + */ + int RAND_pseudo_bytes(void *outdata, size_t size) { @@ -94,6 +157,14 @@ RAND_pseudo_bytes(void *outdata, size_t size) return (*selected_meth->pseudorand)(outdata, size); } +/** + * Return status of the random generator + * + * @return 1 if the random generator can deliver random data. + * + * @ingroup hcrypto_rand + */ + int RAND_status(void) { @@ -101,27 +172,92 @@ RAND_status(void) return (*selected_meth->status)(); } +/** + * Set the default random method. + * + * @param meth set the new default method. + * + * @return 1 on success. + * + * @ingroup hcrypto_rand + */ + int RAND_set_rand_method(const RAND_METHOD *meth) { + const RAND_METHOD *old = selected_meth; selected_meth = meth; + if (old) + (*old->cleanup)(); + if (selected_engine) { + ENGINE_finish(selected_engine); + selected_engine = NULL; + } return 1; } +/** + * Get the default random method. + * + * @ingroup hcrypto_rand + */ + const RAND_METHOD * RAND_get_rand_method(void) { + init_method(); return selected_meth; } +/** + * Set the default random method from engine. + * + * @param engine use engine, if NULL is passed it, old method and engine is cleared. + * + * @return 1 on success, 0 on failure. + * + * @ingroup hcrypto_rand + */ + int RAND_set_rand_engine(ENGINE *engine) { + const RAND_METHOD *meth, *old = selected_meth; + + if (engine) { + ENGINE_up_ref(engine); + meth = ENGINE_get_RAND(engine); + if (meth == NULL) { + ENGINE_finish(engine); + return 0; + } + } else { + meth = NULL; + } + + if (old) + (*old->cleanup)(); + + if (selected_engine) + ENGINE_finish(selected_engine); + + selected_engine = engine; + selected_meth = meth; + return 1; } #define RAND_FILE_SIZE 1024 +/** + * Load a a file and feed it into RAND_seed(). + * + * @param filename name of file to read. + * @param size minimum size to read. + * + * @ingroup hcrypto_rand + */ + int RAND_load_file(const char *filename, size_t size) { @@ -133,7 +269,7 @@ RAND_load_file(const char *filename, size_t size) fd = open(filename, O_RDONLY | O_BINARY, 0600); if (fd < 0) return 0; - + rk_cloexec(fd); len = 0; while(len < size) { slen = read(fd, buf, sizeof(buf)); @@ -147,6 +283,15 @@ RAND_load_file(const char *filename, size_t size) return len ? 1 : 0; } +/** + * Write of random numbers to a file to store for later initiation with RAND_load_file(). + * + * @param filename name of file to write. + * + * @return 1 on success and non-one on failure. + * @ingroup hcrypto_rand + */ + int RAND_write_file(const char *filename) { @@ -157,6 +302,7 @@ RAND_write_file(const char *filename) fd = open(filename, O_WRONLY | O_CREAT | O_BINARY, 0600); if (fd < 0) return 0; + rk_cloexec(fd); len = 0; while(len < RAND_FILE_SIZE) { @@ -175,6 +321,18 @@ RAND_write_file(const char *filename) return res; } +/** + * Return the default random state filename for a user to use for + * RAND_load_file(), and RAND_write_file(). + * + * @param filename buffer to hold file name. + * @param size size of buffer filename. + * + * @return the buffer filename or NULL on failure. + * + * @ingroup hcrypto_rand + */ + const char * RAND_file_name(char *filename, size_t size) { diff --git a/source4/heimdal/lib/hcrypto/rc2.c b/source4/heimdal/lib/hcrypto/rc2.c old mode 100755 new mode 100644 diff --git a/source4/heimdal/lib/hcrypto/rc2.h b/source4/heimdal/lib/hcrypto/rc2.h old mode 100755 new mode 100644 diff --git a/source4/heimdal/lib/hcrypto/rc4.c b/source4/heimdal/lib/hcrypto/rc4.c old mode 100755 new mode 100644 diff --git a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c old mode 100755 new mode 100644 diff --git a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.h b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.h old mode 100755 new mode 100644 diff --git a/source4/heimdal/lib/hcrypto/rnd_keys.c b/source4/heimdal/lib/hcrypto/rnd_keys.c index a035b890b8..0fd64af3b5 100644 --- a/source4/heimdal/lib/hcrypto/rnd_keys.c +++ b/source4/heimdal/lib/hcrypto/rnd_keys.c @@ -34,476 +34,109 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: rnd_keys.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id: rnd_keys.c 23093 2008-04-27 18:49:51Z lha $"); #endif +#define HC_DEPRECATED + #ifdef KRB5 #include #endif #include +#include #include -#include - -#ifdef TIME_WITH_SYS_TIME -#include -#include -#elif defined(HAVE_SYS_TIME_H) -#include -#else -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif - -#ifdef HAVE_SIGNAL_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif - -/* - * Generate "random" data by checksumming a file. - * - * Returns -1 if there were any problems with permissions or I/O - * errors. - */ -static -int -sumFile (const char *name, int len, void *res) -{ - uint32_t sum[2] = { 0, 0 }; - uint32_t buf[1024*2]; - int fd, i; - - fd = open (name, 0); - if (fd < 0) - return -1; - - while (len > 0) - { - int n = read(fd, buf, sizeof(buf)); - if (n < 0) - { - close(fd); - return n; - } - for (i = 0; i < (n/sizeof(buf[0])); i++) - { - sum[0] += buf[i]; - i++; - sum[1] += buf[i]; - } - len -= n; - } - close (fd); - memcpy (res, &sum, sizeof(sum)); - return 0; -} - -#if 0 -static -int -md5sumFile (const char *name, int len, int32_t sum[4]) -{ - int32_t buf[1024*2]; - int fd, cnt; - struct md5 md5; - - fd = open (name, 0); - if (fd < 0) - return -1; - - md5_init(&md5); - while (len > 0) - { - int n = read(fd, buf, sizeof(buf)); - if (n < 0) - { - close(fd); - return n; - } - md5_update(&md5, buf, n); - len -= n; - } - md5_finito(&md5, (unsigned char *)sum); - close (fd); - return 0; -} -#endif - -/* - * 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 uint32_t sequence_index[2]; - -/* - * Random number generator based on ideas from truerand in cryptolib - * as described on page 424 in Applied Cryptography 2 ed. by Bruce - * Schneier. - */ - -static volatile int counter; -static volatile unsigned char *gdata; /* Global data */ -static volatile int igdata; /* Index into global data */ -static int gsize; -#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__) -/* Visual C++ 4.0 (Windows95/NT) */ +#undef __attribute__ +#define __attribute__(X) -static -RETSIGTYPE -sigALRM(int sig) -{ - if (igdata < gsize) - gdata[igdata++] ^= counter & 0xff; - -#ifndef HAVE_SIGACTION - signal(SIGALRM, sigALRM); /* Reinstall SysV signal handler */ -#endif - SIGRETURN(0); -} - -#endif - -#if !defined(HAVE_RANDOM) && defined(HAVE_RAND) -#ifndef srandom -#define srandom srand -#endif -#ifndef random -#define random rand -#endif -#endif - -#if !defined(HAVE_SETITIMER) || defined(WIN32) || defined(__EMX__) || defined(__OS2__) || defined(__CYGWIN32__) -static void -des_not_rand_data(unsigned char *data, int size) -{ - int i; - - srandom (time (NULL)); - - for(i = 0; i < size; ++i) - data[i] ^= random() % 0x100; -} -#endif - -#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__) - -#ifndef HAVE_SETITIMER -static void -pacemaker(struct timeval *tv) -{ - fd_set fds; - pid_t pid; - pid = getppid(); - while(1){ - FD_ZERO(&fds); - FD_SET(0, &fds); - select(1, &fds, NULL, NULL, tv); - kill(pid, SIGALRM); - } -} -#endif - -#ifdef HAVE_SIGACTION -/* XXX ugly hack, should perhaps use function from roken */ -static RETSIGTYPE -(*fake_signal(int sig, RETSIGTYPE (*f)(int)))(int) -{ - struct sigaction sa, osa; - sa.sa_handler = f; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sigaction(sig, &sa, &osa); - return osa.sa_handler; -} -#define signal(S, F) fake_signal((S), (F)) -#endif - -/* - * Generate size bytes of "random" data using timed interrupts. - * It takes about 40ms/byte random data. - * It's not neccessary to be root to run it. - */ -void +void HC_DEPRECATED DES_rand_data(void *outdata, int size) { - unsigned char *data = outdata; - struct itimerval tv, otv; - RETSIGTYPE (*osa)(int); - int i, j; -#ifndef HAVE_SETITIMER - RETSIGTYPE (*ochld)(int); - pid_t pid; -#endif - const char *rnd_devices[] = {"/dev/random", - "/dev/srandom", - "/dev/urandom", - "/dev/arandom", - NULL}; - const char **p; - - for(p = rnd_devices; *p; p++) { - int fd = open(*p, O_RDONLY | O_NDELAY); - - if(fd >= 0 && read(fd, data, size) == size) { - close(fd); - return; - } - close(fd); - } - - /* Paranoia? Initialize data from /dev/mem if we can read it. */ - if (size >= 8) - sumFile("/dev/mem", (1024*1024*2), data); - - gdata = data; - gsize = size; - igdata = 0; - - osa = signal(SIGALRM, sigALRM); - - /* Start timer */ - tv.it_value.tv_sec = 0; - tv.it_value.tv_usec = 10 * 1000; /* 10 ms */ - tv.it_interval = tv.it_value; -#ifdef HAVE_SETITIMER - setitimer(ITIMER_REAL, &tv, &otv); -#else - ochld = signal(SIGCHLD, SIG_IGN); - pid = fork(); - if(pid == -1){ - signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL); - des_not_rand_data(data, size); - return; - } - if(pid == 0) - pacemaker(&tv.it_interval); -#endif - - for(i = 0; i < 4; i++) { - for (igdata = 0; igdata < size;) /* igdata++ in sigALRM */ - counter++; - for (j = 0; j < size; j++) /* Only use 2 bits each lap */ - gdata[j] = (gdata[j]>>2) | (gdata[j]<<6); - } -#ifdef HAVE_SETITIMER - setitimer(ITIMER_REAL, &otv, 0); -#else - kill(pid, SIGKILL); - while(waitpid(pid, NULL, 0) != pid); - signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL); -#endif - signal(SIGALRM, osa != SIG_ERR ? osa : SIG_DFL); -} -#else -void -DES_rand_data(unsigned char *p, int s) -{ - des_not_rand_data (p, s); + RAND_bytes(outdata, size); } -#endif -void +void HC_DEPRECATED DES_generate_random_block(DES_cblock *block) { - DES_rand_data((unsigned char *)block, sizeof(*block)); + RAND_bytes(block, sizeof(*block)); } #define DES_rand_data_key hc_DES_rand_data_key -void +void HC_DEPRECATED DES_rand_data_key(DES_cblock *key); /* - * Generate a "random" DES key. + * Generate a random DES key. */ -void -DES_rand_data_key(DES_cblock *key) -{ - unsigned char data[8]; - DES_key_schedule sched; - do { - DES_rand_data(data, sizeof(data)); - DES_rand_data((unsigned char*)key, sizeof(DES_cblock)); - DES_set_odd_parity(key); - DES_set_key(key, &sched); - DES_ecb_encrypt(&data, key, &sched, DES_ENCRYPT); - memset(&data, 0, sizeof(data)); - memset(&sched, 0, sizeof(sched)); - DES_set_odd_parity(key); - } while(DES_is_weak_key(key)); -} -/* - * Generate "random" data by checksumming /dev/mem - * - * It's neccessary to be root to run it. Returns -1 if there were any - * problems with permissions. - */ - -#define DES_mem_rand8 hc_DES_mem_rand8 - -int -DES_mem_rand8(unsigned char *data); - -int -DES_mem_rand8(unsigned char *data) -{ - return 1; -} - -/* - * In case the generator does not get initialized use this as fallback. - */ -static int initialized; - -static void -do_initialize(void) +void HC_DEPRECATED +DES_rand_data_key(DES_cblock *key) { - DES_cblock default_seed; - do { - DES_generate_random_block(&default_seed); - DES_set_odd_parity(&default_seed); - } while (DES_is_weak_key(&default_seed)); - DES_init_random_number_generator(&default_seed); + DES_new_random_key(key); } -#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 set_sequence_number(ll) \ -memcpy((char *)sequence_index, (ll), sizeof(sequence_index)); - -/* - * Set the sequnce number to this value (a long long). - */ -void +void HC_DEPRECATED DES_set_sequence_number(void *ll) { - set_sequence_number(ll); } -/* - * Set the generator seed and reset the sequence number to 0. - */ -void +void HC_DEPRECATED DES_set_random_generator_seed(DES_cblock *seed) { - DES_set_key(seed, &sequence_seed); - zero_long_long(sequence_index); - initialized = 1; + RAND_seed(seed, sizeof(*seed)); } -/* - * Generate a sequence of random des keys - * using the random block sequence, fixup - * parity and skip weak keys. +/** + * Generate a random des key using a random block, fixup parity and + * skip weak keys. + * + * @param key is set to a random key. + * + * @return 0 on success, non zero on random number generator failure. + * + * @ingroup hcrypto_des */ -int + +int HC_DEPRECATED DES_new_random_key(DES_cblock *key) { - if (!initialized) - do_initialize(); - do { - DES_ecb_encrypt((DES_cblock *) sequence_index, - key, - &sequence_seed, - DES_ENCRYPT); - incr_long_long(sequence_index); - /* random key must have odd parity and not be weak */ + if (RAND_bytes(key, sizeof(*key)) != 1) + return 1; DES_set_odd_parity(key); - } while (DES_is_weak_key(key)); + } while(DES_is_weak_key(key)); + return(0); } -/* - * des_init_random_number_generator: +/** + * Seed the random number generator. Deprecated, use @ref page_rand * - * Initialize the sequence of random 64 bit blocks. The input seed - * can be a secret key since it should be well hidden and is also not - * kept. + * @param seed a seed to seed that random number generate with. * + * @ingroup hcrypto_des */ -void -DES_init_random_number_generator(DES_cblock *seed) -{ - struct timeval now; - DES_cblock uniq; - DES_cblock new_key; - gettimeofday(&now, (struct timezone *)0); - DES_generate_random_block(&uniq); - - /* Pick a unique random key from the shared sequence. */ - DES_set_random_generator_seed(seed); - 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. */ - set_sequence_number((unsigned char *)&now); - DES_new_random_key(&new_key); - DES_set_random_generator_seed(&new_key); -} - -/* This is for backwards compatibility. */ -void -DES_random_key(DES_cblock *ret) +void HC_DEPRECATED +DES_init_random_number_generator(DES_cblock *seed) { - DES_new_random_key(ret); + RAND_seed(seed, sizeof(*seed)); } -#ifdef TESTRUN -int -main() -{ - unsigned char data[8]; - int i; - - while (1) - { - if (sumFile("/dev/mem", (1024*1024*8), data) != 0) - { perror("sumFile"); exit(1); } - for (i = 0; i < 8; i++) - printf("%02x", data[i]); - printf("\n"); - } -} -#endif +/** + * Generate a random key, deprecated since it doesn't return an error + * code, use DES_new_random_key(). + * + * @param key is set to a random key. + * + * @ingroup hcrypto_des + */ -#ifdef TESTRUN2 -int -main() +void HC_DEPRECATED +DES_random_key(DES_cblock *key) { - DES_cblock data; - int i; - - while (1) - { - do_initialize(); - DES_random_key(data); - for (i = 0; i < 8; i++) - printf("%02x", data[i]); - printf("\n"); - } + if (DES_new_random_key(key)) + abort(); } -#endif diff --git a/source4/heimdal/lib/hcrypto/ui.c b/source4/heimdal/lib/hcrypto/ui.c index 3e651998b5..8c3ea1fa15 100644 --- a/source4/heimdal/lib/hcrypto/ui.c +++ b/source4/heimdal/lib/hcrypto/ui.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include -RCSID("$Id: ui.c 18158 2006-09-22 15:45:57Z lha $"); +RCSID("$Id: ui.c 23466 2008-07-27 12:16:15Z lha $"); #endif #include @@ -84,7 +84,9 @@ read_string(const char *preprompt, const char *prompt, if (sigaction(i, &sa, &sigs[i]) == 0) oksigs[i] = 1; - if((tty = fopen("/dev/tty", "r")) == NULL) + if((tty = fopen("/dev/tty", "r")) != NULL) + rk_cloexec_file(tty); + else tty = stdin; fprintf(stderr, "%s%s", preprompt, prompt); @@ -116,7 +118,7 @@ read_string(const char *preprompt, const char *prompt, *p = 0; if(echo == 0){ - printf("\n"); + fprintf(stderr, "\n"); tcsetattr(fileno(tty), TCSANOW, &t_old); } -- cgit