diff options
author | Andrew Bartlett <abartlet@samba.org> | 2008-08-27 11:01:55 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2008-08-27 11:01:55 +1000 |
commit | 8b94f7bcd70b1196487b433e355127a4f84bf5a5 (patch) | |
tree | 940c1838cd0fa4033fef7945e97b530341f99ecf /source4/heimdal/lib/hcrypto | |
parent | ca20c56b260e2799c40b0c7c0e3ef5f7308b586e (diff) | |
parent | 9430420ba246c26489ad51e8b52e13d891436bb3 (diff) | |
download | samba-8b94f7bcd70b1196487b433e355127a4f84bf5a5.tar.gz samba-8b94f7bcd70b1196487b433e355127a4f84bf5a5.tar.bz2 samba-8b94f7bcd70b1196487b433e355127a4f84bf5a5.zip |
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into pac-verify
(This used to be commit 32143287c7eb452c6ed9ccd15e8cd4e5a907b437)
Diffstat (limited to 'source4/heimdal/lib/hcrypto')
53 files changed, 1010 insertions, 304 deletions
diff --git a/source4/heimdal/lib/hcrypto/aes.c b/source4/heimdal/lib/hcrypto/aes.c index a36459a457..668b4f269f 100644 --- a/source4/heimdal/lib/hcrypto/aes.c +++ b/source4/heimdal/lib/hcrypto/aes.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: aes.c 15495 2005-06-18 22:47:33Z lha $"); +RCSID("$Id$"); #endif #ifdef KRB5 diff --git a/source4/heimdal/lib/hcrypto/aes.h b/source4/heimdal/lib/hcrypto/aes.h index eeba5c9e51..9550f61e9f 100644 --- a/source4/heimdal/lib/hcrypto/aes.h +++ b/source4/heimdal/lib/hcrypto/aes.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: aes.h 22958 2008-04-11 11:33:22Z lha $ */ +/* $Id$ */ #ifndef HEIM_AES_H #define HEIM_AES_H 1 diff --git a/source4/heimdal/lib/hcrypto/bn.c b/source4/heimdal/lib/hcrypto/bn.c index 1f8c1d5471..eb2e1c37a5 100644 --- a/source4/heimdal/lib/hcrypto/bn.c +++ b/source4/heimdal/lib/hcrypto/bn.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: bn.c 22850 2008-04-07 18:49:01Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/bn.h b/source4/heimdal/lib/hcrypto/bn.h index 92cacec2a6..924ccf9cec 100644 --- a/source4/heimdal/lib/hcrypto/bn.h +++ b/source4/heimdal/lib/hcrypto/bn.h @@ -32,7 +32,7 @@ */ /* - * $Id: bn.h 22260 2007-12-09 06:23:47Z lha $ + * $Id$ */ #ifndef _HEIM_BN_H diff --git a/source4/heimdal/lib/hcrypto/des.c b/source4/heimdal/lib/hcrypto/des.c index 9e533dd708..8be9d649cd 100644 --- a/source4/heimdal/lib/hcrypto/des.c +++ b/source4/heimdal/lib/hcrypto/des.c @@ -84,7 +84,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: des.c 23117 2008-04-28 10:29:36Z lha $"); +RCSID("$Id$"); #endif #define HC_DEPRECATED diff --git a/source4/heimdal/lib/hcrypto/des.h b/source4/heimdal/lib/hcrypto/des.h index 3c52f59e28..f1a6798851 100644 --- a/source4/heimdal/lib/hcrypto/des.h +++ b/source4/heimdal/lib/hcrypto/des.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: des.h 23148 2008-04-29 05:53:27Z biorn $ */ +/* $Id$ */ #ifndef _DESperate_H #define _DESperate_H 1 diff --git a/source4/heimdal/lib/hcrypto/dh-imath.c b/source4/heimdal/lib/hcrypto/dh-imath.c index 494d436d13..f4e5e118a0 100644 --- a/source4/heimdal/lib/hcrypto/dh-imath.c +++ b/source4/heimdal/lib/hcrypto/dh-imath.c @@ -43,7 +43,7 @@ #include "imath/imath.h" -RCSID("$Id: dh-imath.c 22368 2007-12-28 15:27:52Z lha $"); +RCSID("$Id$"); static void BN2mpz(mpz_t *s, const BIGNUM *bn) diff --git a/source4/heimdal/lib/hcrypto/dh.c b/source4/heimdal/lib/hcrypto/dh.c index 9f1af0b3b1..b2aa890e55 100644 --- a/source4/heimdal/lib/hcrypto/dh.c +++ b/source4/heimdal/lib/hcrypto/dh.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: dh.c 22397 2008-01-01 20:20:31Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/dh.h b/source4/heimdal/lib/hcrypto/dh.h index e34390dc99..533d832a3d 100644 --- a/source4/heimdal/lib/hcrypto/dh.h +++ b/source4/heimdal/lib/hcrypto/dh.h @@ -32,7 +32,7 @@ */ /* - * $Id: dh.h 17483 2006-05-06 13:11:15Z lha $ + * $Id$ */ #ifndef _HEIM_DH_H diff --git a/source4/heimdal/lib/hcrypto/dsa.c b/source4/heimdal/lib/hcrypto/dsa.c index 0dc59dac61..637963a591 100644 --- a/source4/heimdal/lib/hcrypto/dsa.c +++ b/source4/heimdal/lib/hcrypto/dsa.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: dsa.c 17496 2006-05-07 11:31:58Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/dsa.h b/source4/heimdal/lib/hcrypto/dsa.h index 0544b80118..94d8206589 100644 --- a/source4/heimdal/lib/hcrypto/dsa.h +++ b/source4/heimdal/lib/hcrypto/dsa.h @@ -32,7 +32,7 @@ */ /* - * $Id: dsa.h 16564 2006-01-13 15:26:52Z lha $ + * $Id$ */ #ifndef _HEIM_DSA_H diff --git a/source4/heimdal/lib/hcrypto/engine.c b/source4/heimdal/lib/hcrypto/engine.c index 1a754909c5..b26987884d 100644 --- a/source4/heimdal/lib/hcrypto/engine.c +++ b/source4/heimdal/lib/hcrypto/engine.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: engine.c 20828 2007-06-03 05:10:20Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/engine.h b/source4/heimdal/lib/hcrypto/engine.h index 547a2d1324..d317a77e0d 100644 --- a/source4/heimdal/lib/hcrypto/engine.h +++ b/source4/heimdal/lib/hcrypto/engine.h @@ -32,7 +32,7 @@ */ /* - * $Id: engine.h 17475 2006-05-06 12:34:36Z lha $ + * $Id$ */ #ifndef _HEIM_ENGINE_H diff --git a/source4/heimdal/lib/hcrypto/evp-aes-cts.c b/source4/heimdal/lib/hcrypto/evp-aes-cts.c new file mode 100644 index 0000000000..60a538b7de --- /dev/null +++ b/source4/heimdal/lib/hcrypto/evp-aes-cts.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +RCSID("$Id$"); + +#define HC_DEPRECATED + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + + +#include <krb5-types.h> + +#if defined(BUILD_KRB5_LIB) && defined(HAVE_OPENSSL) +#include <openssl/evp.h> +#include <openssl/aes.h> + +#define _hc_EVP_hcrypto_aes_128_cts _krb5_EVP_hcrypto_aes_128_cts +#define _hc_EVP_hcrypto_aes_192_cts _krb5_EVP_hcrypto_aes_192_cts +#define _hc_EVP_hcrypto_aes_256_cts _krb5_EVP_hcrypto_aes_256_cts + +const EVP_CIPHER * _krb5_EVP_hcrypto_aes_128_cts(void); +const EVP_CIPHER * _krb5_EVP_hcrypto_aes_192_cts(void); +const EVP_CIPHER * _krb5_EVP_hcrypto_aes_256_cts(void); + +#else +#include <evp.h> +#include <aes.h> + +#define _hc_EVP_hcrypto_aes_128_cts hc_EVP_hcrypto_aes_128_cts +#define _hc_EVP_hcrypto_aes_192_cts hc_EVP_hcrypto_aes_192_cts +#define _hc_EVP_hcrypto_aes_256_cts hc_EVP_hcrypto_aes_256_cts + +#endif + +/* + * + */ + +static int +aes_cts_init(EVP_CIPHER_CTX *ctx, + const unsigned char * key, + const unsigned char * iv, + int encp) +{ + AES_KEY *k = ctx->cipher_data; + if (ctx->encrypt) + AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k); + else + AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k); + return 1; +} + +static void +_krb5_aes_cts_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec, const int encryptp) +{ + unsigned char tmp[AES_BLOCK_SIZE]; + int i; + + /* + * In the framework of kerberos, the length can never be shorter + * then at least one blocksize. + */ + + if (encryptp) { + + while(len > AES_BLOCK_SIZE) { + for (i = 0; i < AES_BLOCK_SIZE; i++) + tmp[i] = in[i] ^ ivec[i]; + AES_encrypt(tmp, out, key); + memcpy(ivec, out, AES_BLOCK_SIZE); + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + + for (i = 0; i < len; i++) + tmp[i] = in[i] ^ ivec[i]; + for (; i < AES_BLOCK_SIZE; i++) + tmp[i] = 0 ^ ivec[i]; + + AES_encrypt(tmp, out - AES_BLOCK_SIZE, key); + + memcpy(out, ivec, len); + memcpy(ivec, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + + } else { + unsigned char tmp2[AES_BLOCK_SIZE]; + unsigned char tmp3[AES_BLOCK_SIZE]; + + while(len > AES_BLOCK_SIZE * 2) { + memcpy(tmp, in, AES_BLOCK_SIZE); + AES_decrypt(in, out, key); + for (i = 0; i < AES_BLOCK_SIZE; i++) + out[i] ^= ivec[i]; + memcpy(ivec, tmp, AES_BLOCK_SIZE); + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + + len -= AES_BLOCK_SIZE; + + memcpy(tmp, in, AES_BLOCK_SIZE); /* save last iv */ + AES_decrypt(in, tmp2, key); + + memcpy(tmp3, in + AES_BLOCK_SIZE, len); + memcpy(tmp3 + len, tmp2 + len, AES_BLOCK_SIZE - len); /* xor 0 */ + + for (i = 0; i < len; i++) + out[i + AES_BLOCK_SIZE] = tmp2[i] ^ tmp3[i]; + + AES_decrypt(tmp3, out, key); + for (i = 0; i < AES_BLOCK_SIZE; i++) + out[i] ^= ivec[i]; + memcpy(ivec, tmp, AES_BLOCK_SIZE); + } +} + +static int +aes_cts_do_cipher(EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + unsigned int len) +{ + AES_KEY *k = ctx->cipher_data; + + if (len < AES_BLOCK_SIZE) + abort(); /* krb5_abortx(context, "invalid use of AES_CTS_encrypt"); */ + if (len == AES_BLOCK_SIZE) { + if (ctx->encrypt) + AES_encrypt(in, out, k); + else + AES_decrypt(in, out, k); + } else { + _krb5_aes_cts_encrypt(in, out, len, k, ctx->iv, ctx->encrypt); + } + + return 1; +} + + +static int +aes_cts_cleanup(EVP_CIPHER_CTX *ctx) +{ + memset(ctx->cipher_data, 0, sizeof(AES_KEY)); + return 1; +} + +/** + * The AES-128 cts cipher type (hcrypto) + * + * @return the AES-128 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +const EVP_CIPHER * +_hc_EVP_hcrypto_aes_128_cts(void) +{ + static const EVP_CIPHER aes_128_cts = { + 0, + 1, + 16, + 16, + EVP_CIPH_CBC_MODE, + aes_cts_init, + aes_cts_do_cipher, + aes_cts_cleanup, + sizeof(AES_KEY), + NULL, + NULL, + NULL, + NULL + }; + + return &aes_128_cts; +} + +/** + * The AES-192 cts cipher type (hcrypto) + * + * @return the AES-192 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +const EVP_CIPHER * +_hc_EVP_hcrypto_aes_192_cts(void) +{ + static const EVP_CIPHER aes_192_cts = { + 0, + 1, + 24, + 16, + EVP_CIPH_CBC_MODE, + aes_cts_init, + aes_cts_do_cipher, + aes_cts_cleanup, + sizeof(AES_KEY), + NULL, + NULL, + NULL, + NULL + }; + + return &aes_192_cts; +} + +/** + * The AES-256 cts cipher type (hcrypto) + * + * @return the AES-256 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +const EVP_CIPHER * +_hc_EVP_hcrypto_aes_256_cts(void) +{ + static const EVP_CIPHER aes_256_cts = { + 0, + 1, + 32, + 16, + EVP_CIPH_CBC_MODE, + aes_cts_init, + aes_cts_do_cipher, + aes_cts_cleanup, + sizeof(AES_KEY), + NULL, + NULL, + NULL, + NULL + }; + + return &aes_256_cts; +} diff --git a/source4/heimdal/lib/hcrypto/evp-hcrypto.c b/source4/heimdal/lib/hcrypto/evp-hcrypto.c new file mode 100644 index 0000000000..6737fd817e --- /dev/null +++ b/source4/heimdal/lib/hcrypto/evp-hcrypto.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +RCSID("$Id$"); + +#define HC_DEPRECATED + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include <evp.h> + +#include <krb5-types.h> + +#include <aes.h> + +/* + * + */ + +static int +aes_init(EVP_CIPHER_CTX *ctx, + const unsigned char * key, + const unsigned char * iv, + int encp) +{ + AES_KEY *k = ctx->cipher_data; + if (ctx->encrypt) + AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k); + else + AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k); + return 1; +} + +static int +aes_do_cipher(EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + unsigned int size) +{ + AES_KEY *k = ctx->cipher_data; + AES_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt); + return 1; +} + +static int +aes_cleanup(EVP_CIPHER_CTX *ctx) +{ + memset(ctx->cipher_data, 0, sizeof(AES_KEY)); + return 1; +} + +/** + * The AES-128 cipher type (hcrypto) + * + * @return the AES-128 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +const EVP_CIPHER * +EVP_hcrypto_aes_128_cbc(void) +{ + static const EVP_CIPHER aes_128_cbc = { + 0, + 16, + 16, + 16, + EVP_CIPH_CBC_MODE, + aes_init, + aes_do_cipher, + aes_cleanup, + sizeof(AES_KEY), + NULL, + NULL, + NULL, + NULL + }; + + return &aes_128_cbc; +} + +/** + * The AES-192 cipher type (hcrypto) + * + * @return the AES-192 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +const EVP_CIPHER * +EVP_hcrypto_aes_192_cbc(void) +{ + static const EVP_CIPHER aes_192_cbc = { + 0, + 16, + 24, + 16, + EVP_CIPH_CBC_MODE, + aes_init, + aes_do_cipher, + aes_cleanup, + sizeof(AES_KEY), + NULL, + NULL, + NULL, + NULL + }; + return &aes_192_cbc; +} + +/** + * The AES-256 cipher type (hcrypto) + * + * @return the AES-256 EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +const EVP_CIPHER * +EVP_hcrypto_aes_256_cbc(void) +{ + static const EVP_CIPHER aes_256_cbc = { + 0, + 16, + 32, + 16, + EVP_CIPH_CBC_MODE, + aes_init, + aes_do_cipher, + aes_cleanup, + sizeof(AES_KEY), + NULL, + NULL, + NULL, + NULL + }; + return &aes_256_cbc; +} diff --git a/source4/heimdal/lib/hcrypto/evp.c b/source4/heimdal/lib/hcrypto/evp.c index b4fb8a7f23..42b7c6da0b 100644 --- a/source4/heimdal/lib/hcrypto/evp.c +++ b/source4/heimdal/lib/hcrypto/evp.c @@ -35,9 +35,10 @@ #include <config.h> #endif -RCSID("$Id: evp.c 23144 2008-04-29 05:47:16Z lha $"); +RCSID("$Id$"); #define HC_DEPRECATED +#define HC_DEPRECATED_CRYPTO #include <sys/types.h> #include <stdio.h> @@ -49,7 +50,6 @@ RCSID("$Id: evp.c 23144 2008-04-29 05:47:16Z lha $"); #include <krb5-types.h> -#include <aes.h> #include "camellia.h" #include <des.h> #include <sha.h> @@ -63,24 +63,20 @@ RCSID("$Id: evp.c 23144 2008-04-29 05:47:16Z lha $"); * @page page_evp EVP - generic crypto interface * * See the library functions here: @ref hcrypto_evp + * + * @section evp_cipher EVP Cipher + * + * The use of EVP_CipherInit_ex() and EVP_Cipher() is pretty easy to + * understand forward, then EVP_CipherUpdate() and + * EVP_CipherFinal_ex() really needs an example to explain @ref + * example_evp_cipher.c . + * + * @example example_evp_cipher.c + * + * This is an example how to use EVP_CipherInit_ex(), + * EVP_CipherUpdate() and EVP_CipherFinal_ex(). */ - -typedef int (*evp_md_init)(EVP_MD_CTX *); -typedef int (*evp_md_update)(EVP_MD_CTX *,const void *, size_t); -typedef int (*evp_md_final)(void *, EVP_MD_CTX *); -typedef int (*evp_md_cleanup)(EVP_MD_CTX *); - -struct hc_evp_md { - int hash_size; - int block_size; - int ctx_size; - evp_md_init init; - evp_md_update update; - evp_md_final final; - evp_md_cleanup cleanup; -}; - struct hc_EVP_MD_CTX { const EVP_MD *md; ENGINE *engine; @@ -361,9 +357,9 @@ EVP_sha256(void) 32, 64, sizeof(SHA256_CTX), - (evp_md_init)SHA256_Init, - (evp_md_update)SHA256_Update, - (evp_md_final)SHA256_Final, + (hc_evp_md_init)SHA256_Init, + (hc_evp_md_update)SHA256_Update, + (hc_evp_md_final)SHA256_Final, NULL }; return &sha256; @@ -373,9 +369,9 @@ static const struct hc_evp_md sha1 = { 20, 64, sizeof(SHA_CTX), - (evp_md_init)SHA1_Init, - (evp_md_update)SHA1_Update, - (evp_md_final)SHA1_Final, + (hc_evp_md_init)SHA1_Init, + (hc_evp_md_update)SHA1_Update, + (hc_evp_md_final)SHA1_Final, NULL }; @@ -422,9 +418,9 @@ EVP_md5(void) 16, 64, sizeof(MD5_CTX), - (evp_md_init)MD5_Init, - (evp_md_update)MD5_Update, - (evp_md_final)MD5_Final, + (hc_evp_md_init)MD5_Init, + (hc_evp_md_update)MD5_Update, + (hc_evp_md_final)MD5_Final, NULL }; return &md5; @@ -445,9 +441,9 @@ EVP_md4(void) 16, 64, sizeof(MD4_CTX), - (evp_md_init)MD4_Init, - (evp_md_update)MD4_Update, - (evp_md_final)MD4_Final, + (hc_evp_md_init)MD4_Init, + (hc_evp_md_update)MD4_Update, + (hc_evp_md_final)MD4_Final, NULL }; return &md4; @@ -468,9 +464,9 @@ EVP_md2(void) 16, 16, sizeof(MD2_CTX), - (evp_md_init)MD2_Init, - (evp_md_update)MD2_Update, - (evp_md_final)MD2_Final, + (hc_evp_md_init)MD2_Init, + (hc_evp_md_update)MD2_Update, + (hc_evp_md_final)MD2_Final, NULL }; return &md2; @@ -508,9 +504,9 @@ EVP_md_null(void) 0, 0, 0, - (evp_md_init)null_Init, - (evp_md_update)null_Update, - (evp_md_final)null_Final, + (hc_evp_md_init)null_Init, + (hc_evp_md_update)null_Update, + (hc_evp_md_final)null_Final, NULL }; return &null; @@ -769,6 +765,8 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine, const void *key, const void *iv, int encp) { + ctx->buf_len = 0; + if (encp == -1) encp = ctx->encrypt; else @@ -783,6 +781,9 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine, if (ctx->cipher_data == NULL && c->ctx_size != 0) return 0; + /* assume block size is a multiple of 2 */ + ctx->block_mask = EVP_CIPHER_block_size(c) - 1; + } else if (ctx->cipher == NULL) { /* reuse of cipher, but not any cipher ever set! */ return 0; @@ -808,7 +809,138 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine, } /** - * Encypher/decypher data + * Encipher/decipher partial data + * + * @param ctx the cipher context. + * @param out output data from the operation. + * @param outlen output length + * @param in input data to the operation. + * @param inlen length of data. + * + * The output buffer length should at least be EVP_CIPHER_block_size() + * byte longer then the input length. + * + * See @ref evp_cipher for an example how to use this function. + * + * @return 1 on success. + * + * @ingroup hcrypto_evp + */ + +int +EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, void *out, int *outlen, + void *in, size_t inlen) +{ + int ret, left, blocksize; + + *outlen = 0; + + /** + * If there in no spare bytes in the left from last Update and the + * input length is on the block boundery, the EVP_CipherUpdate() + * function can take a shortcut (and preformance gain) and + * directly encrypt the data, otherwise we hav to fix it up and + * store extra it the EVP_CIPHER_CTX. + */ + if (ctx->buf_len == 0 && (inlen & ctx->block_mask) == 0) { + ret = (*ctx->cipher->do_cipher)(ctx, out, in, inlen); + if (ret == 1) + *outlen = inlen; + else + *outlen = 0; + return ret; + } + + + blocksize = EVP_CIPHER_CTX_block_size(ctx); + left = blocksize - ctx->buf_len; + assert(left > 0); + + if (ctx->buf_len) { + + /* if total buffer is smaller then input, store locally */ + if (inlen < left) { + memcpy(ctx->buf + ctx->buf_len, in, inlen); + ctx->buf_len += inlen; + return 1; + } + + /* fill in local buffer and encrypt */ + memcpy(ctx->buf + ctx->buf_len, in, left); + ret = (*ctx->cipher->do_cipher)(ctx, out, ctx->buf, blocksize); + memset(ctx->buf, 0, blocksize); + if (ret != 1) + return ret; + + *outlen += blocksize; + inlen -= left; + in = ((unsigned char *)in) + left; + out = ((unsigned char *)out) + blocksize; + ctx->buf_len = 0; + } + + if (inlen) { + ctx->buf_len = (inlen & ctx->block_mask); + inlen &= ~ctx->block_mask; + + ret = (*ctx->cipher->do_cipher)(ctx, out, in, inlen); + if (ret != 1) + return ret; + + *outlen += inlen; + + in = ((unsigned char *)in) + inlen; + memcpy(ctx->buf, in, ctx->buf_len); + } + + return 1; +} + +/** + * Encipher/decipher final data + * + * @param ctx the cipher context. + * @param out output data from the operation. + * @param outlen output length + * + * The input length needs to be at least EVP_CIPHER_block_size() bytes + * long. + * + * See @ref evp_cipher for an example how to use this function. + * + * @return 1 on success. + * + * @ingroup hcrypto_evp + */ + +int +EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, void *out, int *outlen) +{ + *outlen = 0; + + if (ctx->buf_len) { + int ret, left, blocksize; + + blocksize = EVP_CIPHER_CTX_block_size(ctx); + + left = blocksize - ctx->buf_len; + assert(left > 0); + + /* zero fill local buffer */ + memset(ctx->buf + ctx->buf_len, 0, left); + ret = (*ctx->cipher->do_cipher)(ctx, out, ctx->buf, blocksize); + memset(ctx->buf, 0, blocksize); + if (ret != 1) + return ret; + + *outlen += blocksize; + } + + return 1; +} + +/** + * Encipher/decipher data * * @param ctx the cipher context. * @param out out data from the operation. @@ -1047,6 +1179,71 @@ EVP_rc4_40(void) * */ +static int +des_cbc_init(EVP_CIPHER_CTX *ctx, + const unsigned char * key, + const unsigned char * iv, + int encp) +{ + DES_key_schedule *k = ctx->cipher_data; + DES_cblock deskey; + memcpy(&deskey, key, sizeof(deskey)); + DES_set_key_unchecked(&deskey, k); + return 1; +} + +static int +des_cbc_do_cipher(EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + unsigned int size) +{ + DES_key_schedule *k = ctx->cipher_data; + DES_cbc_encrypt(in, out, size, + k, (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +static int +des_cbc_cleanup(EVP_CIPHER_CTX *ctx) +{ + memset(ctx->cipher_data, 0, sizeof(struct DES_key_schedule)); + return 1; +} + +/** + * The DES cipher type + * + * @return the DES-CBC EVP_CIPHER pointer. + * + * @ingroup hcrypto_evp + */ + +const EVP_CIPHER * +EVP_des_cbc(void) +{ + static const EVP_CIPHER des_ede3_cbc = { + 0, + 8, + 8, + 8, + EVP_CIPH_CBC_MODE, + des_cbc_init, + des_cbc_do_cipher, + des_cbc_cleanup, + sizeof(DES_key_schedule), + NULL, + NULL, + NULL, + NULL + }; + return &des_ede3_cbc; +} + +/* + * + */ + struct des_ede3_cbc { DES_key_schedule ks[3]; }; @@ -1124,42 +1321,6 @@ EVP_des_ede3_cbc(void) return &des_ede3_cbc; } -/* - * - */ - -static int -aes_init(EVP_CIPHER_CTX *ctx, - const unsigned char * key, - const unsigned char * iv, - int encp) -{ - AES_KEY *k = ctx->cipher_data; - if (ctx->encrypt) - AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k); - else - AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k); - return 1; -} - -static int -aes_do_cipher(EVP_CIPHER_CTX *ctx, - unsigned char *out, - const unsigned char *in, - unsigned int size) -{ - AES_KEY *k = ctx->cipher_data; - AES_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt); - return 1; -} - -static int -aes_cleanup(EVP_CIPHER_CTX *ctx) -{ - memset(ctx->cipher_data, 0, sizeof(AES_KEY)); - return 1; -} - /** * The AES-128 cipher type * @@ -1171,22 +1332,7 @@ aes_cleanup(EVP_CIPHER_CTX *ctx) const EVP_CIPHER * EVP_aes_128_cbc(void) { - static const EVP_CIPHER aes_128_cbc = { - 0, - 16, - 16, - 16, - EVP_CIPH_CBC_MODE, - aes_init, - aes_do_cipher, - aes_cleanup, - sizeof(AES_KEY), - NULL, - NULL, - NULL, - NULL - }; - return &aes_128_cbc; + return EVP_hcrypto_aes_128_cbc(); } /** @@ -1200,22 +1346,7 @@ EVP_aes_128_cbc(void) const EVP_CIPHER * EVP_aes_192_cbc(void) { - static const EVP_CIPHER aes_192_cbc = { - 0, - 16, - 24, - 16, - EVP_CIPH_CBC_MODE, - aes_init, - aes_do_cipher, - aes_cleanup, - sizeof(AES_KEY), - NULL, - NULL, - NULL, - NULL - }; - return &aes_192_cbc; + return EVP_hcrypto_aes_192_cbc(); } /** @@ -1229,22 +1360,7 @@ EVP_aes_192_cbc(void) const EVP_CIPHER * EVP_aes_256_cbc(void) { - static const EVP_CIPHER aes_256_cbc = { - 0, - 16, - 32, - 16, - EVP_CIPH_CBC_MODE, - aes_init, - aes_do_cipher, - aes_cleanup, - sizeof(AES_KEY), - NULL, - NULL, - NULL, - NULL - }; - return &aes_256_cbc; + return EVP_hcrypto_aes_256_cbc(); } static int diff --git a/source4/heimdal/lib/hcrypto/evp.h b/source4/heimdal/lib/hcrypto/evp.h index c8f8f80f80..e2c95b929e 100644 --- a/source4/heimdal/lib/hcrypto/evp.h +++ b/source4/heimdal/lib/hcrypto/evp.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: evp.h 23141 2008-04-29 05:47:04Z lha $ */ +/* $Id$ */ #ifndef HEIM_EVP_H #define HEIM_EVP_H 1 @@ -56,6 +56,8 @@ #define EVP_CIPHER_key_length hc_EVP_CIPHER_key_length #define EVP_Cipher hc_EVP_Cipher #define EVP_CipherInit_ex hc_EVP_CipherInit_ex +#define EVP_CipherUpdate hc_EVP_CipherUpdate +#define EVP_CipherFinal_ex hc_EVP_CipherFinal_ex #define EVP_Digest hc_EVP_Digest #define EVP_DigestFinal_ex hc_EVP_DigestFinal_ex #define EVP_DigestInit_ex hc_EVP_DigestInit_ex @@ -72,6 +74,13 @@ #define EVP_aes_128_cbc hc_EVP_aes_128_cbc #define EVP_aes_192_cbc hc_EVP_aes_192_cbc #define EVP_aes_256_cbc hc_EVP_aes_256_cbc +#define EVP_hcrypto_aes_128_cbc hc_EVP_hcrypto_aes_128_cbc +#define EVP_hcrypto_aes_192_cbc hc_EVP_hcrypto_aes_192_cbc +#define EVP_hcrypto_aes_256_cbc hc_EVP_hcrypto_aes_256_cbc +#define EVP_hcrypto_aes_128_cts hc_EVP_hcrypto_aes_128_cts +#define EVP_hcrypto_aes_192_cts hc_EVP_hcrypto_aes_192_cts +#define EVP_hcrypto_aes_256_cts hc_EVP_hcrypto_aes_256_cts +#define EVP_des_cbc hc_EVP_des_cbc #define EVP_des_ede3_cbc hc_EVP_des_ede3_cbc #define EVP_enc_null hc_EVP_enc_null #define EVP_md2 hc_EVP_md2 @@ -121,6 +130,7 @@ struct hc_CIPHER { * cipher is used in (use EVP_CIPHER.._mode() to extract the * mode). The rest of the flag field is a bitfield. */ +#define EVP_CIPH_STREAM_CIPHER 0 #define EVP_CIPH_CBC_MODE 2 #define EVP_CIPH_MODE 0x7 @@ -141,7 +151,7 @@ struct hc_CIPHER_CTX { const EVP_CIPHER *cipher; ENGINE *engine; int encrypt; - int buf_len; + int buf_len; /* bytes stored in buf for EVP_CipherUpdate */ unsigned char oiv[EVP_MAX_IV_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char buf[EVP_MAX_BLOCK_LENGTH]; @@ -155,6 +165,21 @@ struct hc_CIPHER_CTX { unsigned char final[EVP_MAX_BLOCK_LENGTH]; }; +typedef int (*hc_evp_md_init)(EVP_MD_CTX *); +typedef int (*hc_evp_md_update)(EVP_MD_CTX *,const void *, size_t); +typedef int (*hc_evp_md_final)(void *, EVP_MD_CTX *); +typedef int (*hc_evp_md_cleanup)(EVP_MD_CTX *); + +struct hc_evp_md { + int hash_size; + int block_size; + int ctx_size; + hc_evp_md_init init; + hc_evp_md_update update; + hc_evp_md_final final; + hc_evp_md_cleanup cleanup; +}; + #if !defined(__GNUC__) && !defined(__attribute__) #define __attribute__(x) #endif @@ -162,6 +187,10 @@ struct hc_CIPHER_CTX { #ifndef HC_DEPRECATED #define HC_DEPRECATED __attribute__((deprecated)) #endif +#ifndef HC_DEPRECATED_CRYPTO +#define HC_DEPRECATED_CRYPTO __attribute__((deprecated)) +#endif + #ifdef __cplusplus extern "C" { @@ -172,9 +201,9 @@ extern "C" { */ const EVP_MD *EVP_md_null(void); -const EVP_MD *EVP_md2(void); -const EVP_MD *EVP_md4(void); -const EVP_MD *EVP_md5(void); +const EVP_MD *EVP_md2(void) HC_DEPRECATED_CRYPTO; +const EVP_MD *EVP_md4(void) HC_DEPRECATED_CRYPTO; +const EVP_MD *EVP_md5(void) HC_DEPRECATED_CRYPTO; const EVP_MD *EVP_sha(void); const EVP_MD *EVP_sha1(void); const EVP_MD *EVP_sha256(void); @@ -182,13 +211,20 @@ const EVP_MD *EVP_sha256(void); const EVP_CIPHER * EVP_aes_128_cbc(void); const EVP_CIPHER * EVP_aes_192_cbc(void); const EVP_CIPHER * EVP_aes_256_cbc(void); +const EVP_CIPHER * EVP_hcrypto_aes_128_cbc(void); +const EVP_CIPHER * EVP_hcrypto_aes_192_cbc(void); +const EVP_CIPHER * EVP_hcrypto_aes_256_cbc(void); +const EVP_CIPHER * EVP_hcrypto_aes_128_cts(void); +const EVP_CIPHER * EVP_hcrypto_aes_192_cts(void); +const EVP_CIPHER * EVP_hcrypto_aes_256_cts(void); +const EVP_CIPHER * EVP_des_cbc(void) HC_DEPRECATED_CRYPTO; const EVP_CIPHER * EVP_des_ede3_cbc(void); const EVP_CIPHER * EVP_enc_null(void); -const EVP_CIPHER * EVP_rc2_40_cbc(void); -const EVP_CIPHER * EVP_rc2_64_cbc(void); -const EVP_CIPHER * EVP_rc2_cbc(void); +const EVP_CIPHER * EVP_rc2_40_cbc(void) HC_DEPRECATED_CRYPTO; +const EVP_CIPHER * EVP_rc2_64_cbc(void) HC_DEPRECATED_CRYPTO; +const EVP_CIPHER * EVP_rc2_cbc(void) HC_DEPRECATED_CRYPTO; const EVP_CIPHER * EVP_rc4(void); -const EVP_CIPHER * EVP_rc4_40(void); +const EVP_CIPHER * EVP_rc4_40(void) HC_DEPRECATED_CRYPTO; const EVP_CIPHER * EVP_camellia_128_cbc(void); const EVP_CIPHER * EVP_camellia_192_cbc(void); const EVP_CIPHER * EVP_camellia_256_cbc(void); @@ -245,6 +281,8 @@ void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *, void *); int EVP_CipherInit_ex(EVP_CIPHER_CTX *,const EVP_CIPHER *, ENGINE *, const void *, const void *, int); +int EVP_CipherUpdate(EVP_CIPHER_CTX *, void *, int *, void *, size_t); +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *, void *, int *); int EVP_Cipher(EVP_CIPHER_CTX *,void *,const void *,size_t); diff --git a/source4/heimdal/lib/hcrypto/hash.h b/source4/heimdal/lib/hcrypto/hash.h index d19f0c0ae1..0b12bddbb7 100644 --- a/source4/heimdal/lib/hcrypto/hash.h +++ b/source4/heimdal/lib/hcrypto/hash.h @@ -30,7 +30,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: hash.h 17450 2006-05-05 11:11:43Z lha $ */ +/* $Id$ */ /* stuff in common between md4, md5, and sha1 */ diff --git a/source4/heimdal/lib/hcrypto/hmac.h b/source4/heimdal/lib/hcrypto/hmac.h index 5bdae0a369..345016db27 100644 --- a/source4/heimdal/lib/hcrypto/hmac.h +++ b/source4/heimdal/lib/hcrypto/hmac.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: hmac.h 16564 2006-01-13 15:26:52Z lha $ */ +/* $Id$ */ #ifndef HEIM_HMAC_H #define HEIM_HMAC_H 1 diff --git a/source4/heimdal/lib/hcrypto/imath/LICENSE b/source4/heimdal/lib/hcrypto/imath/LICENSE index 53dd364c2b..96b231720d 100644 --- a/source4/heimdal/lib/hcrypto/imath/LICENSE +++ b/source4/heimdal/lib/hcrypto/imath/LICENSE @@ -1,4 +1,4 @@ -IMath is Copyright 2002-2007 Michael J. Fromberger +IMath is Copyright © 2002-2008 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/imath/imath.c b/source4/heimdal/lib/hcrypto/imath/imath.c index 4487029f78..d8e170aedd 100755..100644 --- a/source4/heimdal/lib/hcrypto/imath/imath.c +++ b/source4/heimdal/lib/hcrypto/imath/imath.c @@ -1,8 +1,8 @@ /* Name: imath.c Purpose: Arbitrary precision integer arithmetic routines. - Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/> - Info: $Id: imath.c 22648 2008-02-25 07:37:57Z lha $ + Author: M. J. Fromberger <http://spinning-yarns.org/michael/> + Info: $Id: imath.c 645 2008-08-03 04:00:30Z sting $ Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. @@ -53,6 +53,7 @@ const mp_result MP_RANGE = -3; /* argument out of range */ const mp_result MP_UNDEF = -4; /* result undefined */ const mp_result MP_TRUNC = -5; /* output truncated */ const mp_result MP_BADARG = -6; /* invalid null argument */ +const mp_result MP_MINERR = -6; const mp_sign MP_NEG = 1; /* value is strictly negative */ const mp_sign MP_ZPOS = 0; /* value is non-negative */ @@ -65,7 +66,7 @@ static const char *s_error_msg[] = { "argument out of range", "result undefined", "output truncated", - "invalid null argument", + "invalid argument", NULL }; @@ -97,14 +98,7 @@ static const double s_log2[] = { 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ - 0.193426404, 0.191958720, 0.190551412, 0.189200360, /* 36 37 38 39 */ - 0.187901825, 0.186652411, 0.185449023, 0.184288833, /* 40 41 42 43 */ - 0.183169251, 0.182087900, 0.181042597, 0.180031327, /* 44 45 46 47 */ - 0.179052232, 0.178103594, 0.177183820, 0.176291434, /* 48 49 50 51 */ - 0.175425064, 0.174583430, 0.173765343, 0.172969690, /* 52 53 54 55 */ - 0.172195434, 0.171441601, 0.170707280, 0.169991616, /* 56 57 58 59 */ - 0.169293808, 0.168613099, 0.167948779, 0.167300179, /* 60 61 62 63 */ - 0.166666667 + 0.193426404, /* 36 */ }; /* }}} */ @@ -130,31 +124,38 @@ memcpy(q__,p__,i__);}while(0) #define REV(T, A, N) \ do{T *u_=(A),*v_=u_+(N)-1;while(u_<v_){T xch=*u_;*u_++=*v_;*v_--=xch;}}while(0) -#if TRACEABLE_CLAMP -#define CLAMP(Z) s_clamp(Z) -#else #define CLAMP(Z) \ do{mp_int z_=(Z);mp_size uz_=MP_USED(z_);mp_digit *dz_=MP_DIGITS(z_)+uz_-1;\ while(uz_ > 1 && (*dz_-- == 0)) --uz_;MP_USED(z_)=uz_;}while(0) -#endif +/* Select min/max. Do not provide expressions for which multiple + evaluation would be problematic, e.g. x++ */ #define MIN(A, B) ((B)<(A)?(B):(A)) #define MAX(A, B) ((B)>(A)?(B):(A)) + +/* Exchange lvalues A and B of type T, e.g. + SWAP(int, x, y) where x and y are variables of type int. */ #define SWAP(T, A, B) do{T t_=(A);A=(B);B=t_;}while(0) +/* Used to set up and access simple temp stacks within functions. */ #define TEMP(K) (temp + (K)) #define SETUP(E, C) \ do{if((res = (E)) != MP_OK) goto CLEANUP; ++(C);}while(0) +/* Compare value to zero. */ #define CMPZ(Z) \ (((Z)->used==1&&(Z)->digits[0]==0)?0:((Z)->sign==MP_NEG)?-1:1) +/* Multiply X by Y into Z, ignoring signs. Requires that Z have + enough storage preallocated to hold the result. */ #define UMUL(X, Y, Z) \ do{mp_size ua_=MP_USED(X),ub_=MP_USED(Y);mp_size o_=ua_+ub_;\ ZERO(MP_DIGITS(Z),o_);\ (void) s_kmul(MP_DIGITS(X),MP_DIGITS(Y),MP_DIGITS(Z),ua_,ub_);\ MP_USED(Z)=o_;CLAMP(Z);}while(0) +/* Square X into Z. Requires that Z have enough storage to hold the + result. */ #define USQR(X, Z) \ do{mp_size ua_=MP_USED(X),o_=ua_+ua_;ZERO(MP_DIGITS(Z),o_);\ (void) s_ksqr(MP_DIGITS(X),MP_DIGITS(Z),ua_);MP_USED(Z)=o_;CLAMP(Z);}while(0) @@ -194,25 +195,20 @@ static void s_free(void *ptr); necessary. Returns true if successful, false if out of memory. */ static int s_pad(mp_int z, mp_size min); -/* Normalize by removing leading zeroes (except when z = 0) */ -#if TRACEABLE_CLAMP -static void s_clamp(mp_int z); -#endif - /* Fill in a "fake" mp_int on the stack with a given value */ -static void s_fake(mp_int z, int value, mp_digit vbuf[]); +static void s_fake(mp_int z, mp_small value, mp_digit vbuf[]); /* Compare two runs of digits of given length, returns <0, 0, >0 */ static int s_cdig(mp_digit *da, mp_digit *db, mp_size len); /* Pack the unsigned digits of v into array t */ -static int s_vpack(int v, mp_digit t[]); +static int s_vpack(mp_small v, mp_digit t[]); /* Compare magnitudes of a and b, returns <0, 0, >0 */ static int s_ucmp(mp_int a, mp_int b); /* Compare magnitudes of a and v, returns <0, 0, >0 */ -static int s_vcmp(mp_int a, int v); +static int s_vcmp(mp_int a, mp_small v); /* Unsigned magnitude addition; assumes dc is big enough. Carry out is returned (no memory allocated). */ @@ -272,7 +268,7 @@ static int s_dp2k(mp_int z); static int s_isp2(mp_int z); /* Set z to 2^k. May allocate; returns false in case this fails. */ -static int s_2expt(mp_int z, int k); +static int s_2expt(mp_int z, mp_small k); /* Normalize a and b for division, returns normalization constant */ static int s_norm(mp_int a, mp_int b); @@ -410,7 +406,7 @@ mp_result mp_int_init_copy(mp_int z, mp_int old) /* {{{ mp_int_init_value(z, value) */ -mp_result mp_int_init_value(mp_int z, int value) +mp_result mp_int_init_value(mp_int z, mp_small value) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -423,7 +419,7 @@ mp_result mp_int_init_value(mp_int z, int value) /* {{{ mp_int_set_value(z, value) */ -mp_result mp_int_set_value(mp_int z, int value) +mp_result mp_int_set_value(mp_int z, mp_small value) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -589,12 +585,18 @@ mp_result mp_int_add(mp_int a, mp_int b, mp_int c) mp_int x, y; int cmp = s_ucmp(a, b); /* magnitude comparision, sign ignored */ - /* Set x to max(a, b), y to min(a, b) to simplify later code */ - if(cmp >= 0) { - x = a; y = b; - } + /* Set x to max(a, b), y to min(a, b) to simplify later code. + A special case yields zero for equal magnitudes. + */ + if(cmp == 0) { + mp_int_zero(c); + return MP_OK; + } + else if(cmp < 0) { + x = b; y = a; + } else { - x = b; y = a; + x = a; y = b; } if(!s_pad(c, MP_USED(x))) @@ -616,7 +618,7 @@ mp_result mp_int_add(mp_int a, mp_int b, mp_int c) /* {{{ mp_int_add_value(a, value, c) */ -mp_result mp_int_add_value(mp_int a, int value, mp_int c) +mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -694,7 +696,7 @@ mp_result mp_int_sub(mp_int a, mp_int b, mp_int c) /* {{{ mp_int_sub_value(a, value, c) */ -mp_result mp_int_sub_value(mp_int a, int value, mp_int c) +mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -770,7 +772,7 @@ mp_result mp_int_mul(mp_int a, mp_int b, mp_int c) /* {{{ mp_int_mul_value(a, value, c) */ -mp_result mp_int_mul_value(mp_int a, int value, mp_int c) +mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -784,7 +786,7 @@ mp_result mp_int_mul_value(mp_int a, int value, mp_int c) /* {{{ mp_int_mul_pow2(a, p2, c) */ -mp_result mp_int_mul_pow2(mp_int a, int p2, mp_int c) +mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c) { mp_result res; CHECK(a != NULL && c != NULL && p2 >= 0); @@ -896,16 +898,22 @@ mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r) or to overlap with the inputs. */ if((lg = s_isp2(b)) < 0) { - if(q && b != q && (res = mp_int_copy(a, q)) == MP_OK) { - qout = q; + if(q && b != q) { + if((res = mp_int_copy(a, q)) != MP_OK) + goto CLEANUP; + else + qout = q; } else { qout = TEMP(last); SETUP(mp_int_init_copy(TEMP(last), a), last); } - if(r && a != r && (res = mp_int_copy(b, r)) == MP_OK) { - rout = r; + if(r && a != r) { + if((res = mp_int_copy(b, r)) != MP_OK) + goto CLEANUP; + else + rout = r; } else { rout = TEMP(last); @@ -981,7 +989,7 @@ mp_result mp_int_mod(mp_int a, mp_int m, mp_int c) /* {{{ mp_int_div_value(a, value, q, r) */ -mp_result mp_int_div_value(mp_int a, int value, mp_int q, int *r) +mp_result mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r) { mpz_t vtmp, rtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -1005,7 +1013,7 @@ mp_result mp_int_div_value(mp_int a, int value, mp_int q, int *r) /* {{{ mp_int_div_pow2(a, p2, q, r) */ -mp_result mp_int_div_pow2(mp_int a, int p2, mp_int q, mp_int r) +mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r) { mp_result res = MP_OK; @@ -1024,7 +1032,7 @@ mp_result mp_int_div_pow2(mp_int a, int p2, mp_int q, mp_int r) /* {{{ mp_int_expt(a, b, c) */ -mp_result mp_int_expt(mp_int a, int b, mp_int c) +mp_result mp_int_expt(mp_int a, mp_small b, mp_int c) { mpz_t t; mp_result res; @@ -1058,7 +1066,7 @@ mp_result mp_int_expt(mp_int a, int b, mp_int c) /* {{{ mp_int_expt_value(a, b, c) */ -mp_result mp_int_expt_value(int a, int b, mp_int c) +mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c) { mpz_t t; mp_result res; @@ -1149,7 +1157,7 @@ int mp_int_compare_zero(mp_int z) /* {{{ mp_int_compare_value(z, value) */ -int mp_int_compare_value(mp_int z, int value) +int mp_int_compare_value(mp_int z, mp_small value) { mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS; int cmp; @@ -1224,7 +1232,7 @@ mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c) /* {{{ mp_int_exptmod_evalue(a, value, m, c) */ -mp_result mp_int_exptmod_evalue(mp_int a, int value, mp_int m, mp_int c) +mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -1238,7 +1246,7 @@ mp_result mp_int_exptmod_evalue(mp_int a, int value, mp_int m, mp_int c) /* {{{ mp_int_exptmod_bvalue(v, b, m, c) */ -mp_result mp_int_exptmod_bvalue(int value, mp_int b, +mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c) { mpz_t vtmp; @@ -1555,11 +1563,45 @@ mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, /* }}} */ +/* {{{ mp_int_lcm(a, b, c) */ + +mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c) +{ + mpz_t lcm; + mp_result res; + + CHECK(a != NULL && b != NULL && c != NULL); + + /* Since a * b = gcd(a, b) * lcm(a, b), we can compute + lcm(a, b) = (a / gcd(a, b)) * b. + + This formulation insures everything works even if the input + variables share space. + */ + if((res = mp_int_init(&lcm)) != MP_OK) + return res; + if((res = mp_int_gcd(a, b, &lcm)) != MP_OK) + goto CLEANUP; + if((res = mp_int_div(a, &lcm, &lcm, NULL)) != MP_OK) + goto CLEANUP; + if((res = mp_int_mul(&lcm, b, &lcm)) != MP_OK) + goto CLEANUP; + + res = mp_int_copy(&lcm, c); + + CLEANUP: + mp_int_clear(&lcm); + + return res; +} + +/* }}} */ + /* {{{ mp_int_divisible_value(a, v) */ -int mp_int_divisible_value(mp_int a, int v) +int mp_int_divisible_value(mp_int a, mp_small v) { - int rem = 0; + mp_small rem = 0; if(mp_int_div_value(a, v, NULL, &rem) != MP_OK) return 0; @@ -1580,61 +1622,87 @@ int mp_int_is_pow2(mp_int z) /* }}} */ -/* {{{ mp_int_sqrt(a, c) */ +/* {{{ mp_int_root(a, b, c) */ -mp_result mp_int_sqrt(mp_int a, mp_int c) +/* Implementation of Newton's root finding method, based loosely on a + patch contributed by Hal Finkel <half@halssoftware.com> + modified by M. J. Fromberger. + */ +mp_result mp_int_root(mp_int a, mp_small b, mp_int c) { mp_result res = MP_OK; - mpz_t temp[2]; + mpz_t temp[5]; int last = 0; + int flips = 0; - CHECK(a != NULL && c != NULL); + CHECK(a != NULL && c != NULL && b > 0); - /* The square root of a negative value does not exist in the integers. */ - if(MP_SIGN(a) == MP_NEG) - return MP_UNDEF; + if(b == 1) { + return mp_int_copy(a, c); + } + if(MP_SIGN(a) == MP_NEG) { + if(b % 2 == 0) + return MP_UNDEF; /* root does not exist for negative a with even b */ + else + flips = 1; + } SETUP(mp_int_init_copy(TEMP(last), a), last); + SETUP(mp_int_init_copy(TEMP(last), a), last); + SETUP(mp_int_init(TEMP(last)), last); + SETUP(mp_int_init(TEMP(last)), last); SETUP(mp_int_init(TEMP(last)), last); + (void) mp_int_abs(TEMP(0), TEMP(0)); + (void) mp_int_abs(TEMP(1), TEMP(1)); + for(;;) { - if((res = mp_int_sqr(TEMP(0), TEMP(1))) != MP_OK) + if((res = mp_int_expt(TEMP(1), b, TEMP(2))) != MP_OK) goto CLEANUP; - if(mp_int_compare_unsigned(a, TEMP(1)) == 0) break; + if(mp_int_compare_unsigned(TEMP(2), TEMP(0)) <= 0) + break; - if((res = mp_int_copy(a, TEMP(1))) != MP_OK) + if((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK) goto CLEANUP; - if((res = mp_int_div(TEMP(1), TEMP(0), TEMP(1), NULL)) != MP_OK) + if((res = mp_int_expt(TEMP(1), b - 1, TEMP(3))) != MP_OK) goto CLEANUP; - if((res = mp_int_add(TEMP(0), TEMP(1), TEMP(1))) != MP_OK) + if((res = mp_int_mul_value(TEMP(3), b, TEMP(3))) != MP_OK) goto CLEANUP; - if((res = mp_int_div_pow2(TEMP(1), 1, TEMP(1), NULL)) != MP_OK) + if((res = mp_int_div(TEMP(2), TEMP(3), TEMP(4), NULL)) != MP_OK) + goto CLEANUP; + if((res = mp_int_sub(TEMP(1), TEMP(4), TEMP(4))) != MP_OK) goto CLEANUP; - if(mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0) break; - if((res = mp_int_sub_value(TEMP(0), 1, TEMP(0))) != MP_OK) goto CLEANUP; - if(mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0) break; - - if((res = mp_int_copy(TEMP(1), TEMP(0))) != MP_OK) goto CLEANUP; + if(mp_int_compare_unsigned(TEMP(1), TEMP(4)) == 0) { + if((res = mp_int_sub_value(TEMP(4), 1, TEMP(4))) != MP_OK) + goto CLEANUP; + } + if((res = mp_int_copy(TEMP(4), TEMP(1))) != MP_OK) + goto CLEANUP; } - res = mp_int_copy(TEMP(0), c); + if((res = mp_int_copy(TEMP(1), c)) != MP_OK) + goto CLEANUP; + + /* If the original value of a was negative, flip the output sign. */ + if(flips) + (void) mp_int_neg(c, c); /* cannot fail */ CLEANUP: while(--last >= 0) mp_int_clear(TEMP(last)); - - return res; + + return res; } /* }}} */ /* {{{ mp_int_to_int(z, out) */ -mp_result mp_int_to_int(mp_int z, int *out) +mp_result mp_int_to_int(mp_int z, mp_small *out) { - unsigned int uv = 0; + mp_usmall uv = 0; mp_size uz; mp_digit *dz; mp_sign sz; @@ -1643,8 +1711,8 @@ mp_result mp_int_to_int(mp_int z, int *out) /* Make sure the value is representable as an int */ sz = MP_SIGN(z); - if((sz == MP_ZPOS && mp_int_compare_value(z, INT_MAX) > 0) || - mp_int_compare_value(z, INT_MIN) < 0) + if((sz == MP_ZPOS && mp_int_compare_value(z, MP_SMALL_MAX) > 0) || + mp_int_compare_value(z, MP_SMALL_MIN) < 0) return MP_RANGE; uz = MP_USED(z); @@ -1657,13 +1725,46 @@ mp_result mp_int_to_int(mp_int z, int *out) } if(out) - *out = (sz == MP_NEG) ? -(int)uv : (int)uv; + *out = (sz == MP_NEG) ? -(mp_small)uv : (mp_small)uv; return MP_OK; } /* }}} */ +/* {{{ mp_int_to_uint(z, *out) */ + +mp_result mp_int_to_uint(mp_int z, mp_usmall *out) +{ + mp_usmall uv = 0; + mp_size uz; + mp_digit *dz; + mp_sign sz; + + CHECK(z != NULL); + + /* Make sure the value is representable as an int */ + sz = MP_SIGN(z); + if(!(sz == MP_ZPOS && mp_int_compare_value(z, UINT_MAX) <= 0)) + return MP_RANGE; + + uz = MP_USED(z); + dz = MP_DIGITS(z) + uz - 1; + + while(uz > 0) { + uv <<= MP_DIGIT_BIT/2; + uv = (uv << (MP_DIGIT_BIT/2)) | *dz--; + --uz; + } + + if(out) + *out = uv; + + return MP_OK; +} + +/* }}} */ + /* {{{ mp_int_to_string(z, radix, str, limit) */ mp_result mp_int_to_string(mp_int z, mp_size radix, @@ -1769,7 +1870,7 @@ mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **e return MP_RANGE; /* Skip leading whitespace */ - while(isspace((unsigned char)*str)) + while(isspace((int)*str)) ++str; /* Handle leading sign tag (+/-, positive default) */ @@ -2091,26 +2192,9 @@ static int s_pad(mp_int z, mp_size min) /* }}} */ -/* {{{ s_clamp(z) */ - -#if TRACEABLE_CLAMP -static void s_clamp(mp_int z) -{ - mp_size uz = MP_USED(z); - mp_digit *zd = MP_DIGITS(z) + uz - 1; - - while(uz > 1 && (*zd-- == 0)) - --uz; - - MP_USED(z) = uz; -} -#endif - -/* }}} */ - /* {{{ s_fake(z, value, vbuf) */ -static void s_fake(mp_int z, int value, mp_digit vbuf[]) +static void s_fake(mp_int z, mp_small value, mp_digit vbuf[]) { mp_size uv = (mp_size) s_vpack(value, vbuf); @@ -2142,9 +2226,9 @@ static int s_cdig(mp_digit *da, mp_digit *db, mp_size len) /* {{{ s_vpack(v, t[]) */ -static int s_vpack(int v, mp_digit t[]) +static int s_vpack(mp_small v, mp_digit t[]) { - unsigned int uv = (unsigned int)((v < 0) ? -v : v); + mp_usmall uv = (mp_usmall) ((v < 0) ? -v : v); int ndig = 0; if(uv == 0) @@ -2180,7 +2264,7 @@ static int s_ucmp(mp_int a, mp_int b) /* {{{ s_vcmp(a, v) */ -static int s_vcmp(mp_int a, int v) +static int s_vcmp(mp_int a, mp_small v) { mp_digit vdig[MP_VALUE_DIGITS(v)]; int ndig = 0; @@ -2814,7 +2898,7 @@ static int s_isp2(mp_int z) /* {{{ s_2expt(z, k) */ -static int s_2expt(mp_int z, int k) +static int s_2expt(mp_int z, mp_small k) { mp_size ndig, rest; mp_digit *dz; @@ -3100,12 +3184,13 @@ static mp_result s_udiv(mp_int a, mp_int b) /* {{{ s_outlen(z, r) */ -/* Precondition: 2 <= r < 64 */ static int s_outlen(mp_int z, mp_size r) { mp_result bits; double raw; + assert(r >= MP_MIN_RADIX && r <= MP_MAX_RADIX); + bits = mp_int_count_bits(z); raw = (double)bits * s_log2[r]; @@ -3135,7 +3220,7 @@ static int s_ch2val(char c, int r) if(isdigit((unsigned char) c)) out = c - '0'; else if(r > 10 && isalpha((unsigned char) c)) - out = toupper((unsigned char)c) - 'A' + 10; + out = toupper(c) - 'A' + 10; else return -1; diff --git a/source4/heimdal/lib/hcrypto/imath/imath.h b/source4/heimdal/lib/hcrypto/imath/imath.h index f13c09d1a2..cb877959e9 100755..100644 --- a/source4/heimdal/lib/hcrypto/imath/imath.h +++ b/source4/heimdal/lib/hcrypto/imath/imath.h @@ -1,8 +1,8 @@ /* Name: imath.h Purpose: Arbitrary precision integer arithmetic routines. - Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/> - Info: $Id: imath.h 20764 2007-06-01 03:55:14Z lha $ + Author: M. J. Fromberger <http://spinning-yarns.org/michael/> + Info: $Id: imath.h 635 2008-01-08 18:19:40Z sting $ Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. @@ -39,6 +39,8 @@ extern "C" { typedef unsigned char mp_sign; typedef unsigned int mp_size; typedef int mp_result; +typedef long mp_small; /* must be a signed type */ +typedef unsigned long mp_usmall; /* must be an unsigned type */ #ifdef USE_LONG_LONG typedef unsigned int mp_digit; typedef unsigned long long mp_word; @@ -68,9 +70,14 @@ extern const mp_result MP_RANGE; extern const mp_result MP_UNDEF; extern const mp_result MP_TRUNC; extern const mp_result MP_BADARG; +extern const mp_result MP_MINERR; #define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT) #define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT) +#define MP_SMALL_MIN LONG_MIN +#define MP_SMALL_MAX LONG_MAX +#define MP_USMALL_MIN ULONG_MIN +#define MP_USMALL_MAX ULONG_MAX #ifdef USE_LONG_LONG # ifndef ULONG_LONG_MAX @@ -108,8 +115,8 @@ mp_result mp_int_init(mp_int z); mp_int mp_int_alloc(void); mp_result mp_int_init_size(mp_int z, mp_size prec); mp_result mp_int_init_copy(mp_int z, mp_int old); -mp_result mp_int_init_value(mp_int z, int value); -mp_result mp_int_set_value(mp_int z, int value); +mp_result mp_int_init_value(mp_int z, mp_small value); +mp_result mp_int_set_value(mp_int z, mp_small value); void mp_int_clear(mp_int z); void mp_int_free(mp_int z); @@ -119,40 +126,40 @@ void mp_int_zero(mp_int z); /* z = 0 */ mp_result mp_int_abs(mp_int a, mp_int c); /* c = |a| */ mp_result mp_int_neg(mp_int a, mp_int c); /* c = -a */ mp_result mp_int_add(mp_int a, mp_int b, mp_int c); /* c = a + b */ -mp_result mp_int_add_value(mp_int a, int value, mp_int c); +mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c); mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); /* c = a - b */ -mp_result mp_int_sub_value(mp_int a, int value, mp_int c); +mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c); mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); /* c = a * b */ -mp_result mp_int_mul_value(mp_int a, int value, mp_int c); -mp_result mp_int_mul_pow2(mp_int a, int p2, mp_int c); +mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c); +mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c); mp_result mp_int_sqr(mp_int a, mp_int c); /* c = a * a */ mp_result mp_int_div(mp_int a, mp_int b, /* q = a / b */ mp_int q, mp_int r); /* r = a % b */ -mp_result mp_int_div_value(mp_int a, int value, /* q = a / value */ - mp_int q, int *r); /* r = a % value */ -mp_result mp_int_div_pow2(mp_int a, int p2, /* q = a / 2^p2 */ +mp_result mp_int_div_value(mp_int a, mp_small value, /* q = a / value */ + mp_int q, mp_small *r); /* r = a % value */ +mp_result mp_int_div_pow2(mp_int a, mp_small p2, /* q = a / 2^p2 */ mp_int q, mp_int r); /* r = q % 2^p2 */ mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); /* c = a % m */ #define mp_int_mod_value(A, V, R) mp_int_div_value((A), (V), 0, (R)) -mp_result mp_int_expt(mp_int a, int b, mp_int c); /* c = a^b */ -mp_result mp_int_expt_value(int a, int b, mp_int c); /* c = a^b */ +mp_result mp_int_expt(mp_int a, mp_small b, mp_int c); /* c = a^b */ +mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c); /* c = a^b */ int mp_int_compare(mp_int a, mp_int b); /* a <=> b */ int mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */ -int mp_int_compare_zero(mp_int z); /* a <=> 0 */ -int mp_int_compare_value(mp_int z, int value); /* a <=> v */ +int mp_int_compare_zero(mp_int z); /* a <=> 0 */ +int mp_int_compare_value(mp_int z, mp_small value); /* a <=> v */ /* Returns true if v|a, false otherwise (including errors) */ -int mp_int_divisible_value(mp_int a, int v); +int mp_int_divisible_value(mp_int a, mp_small v); /* Returns k >= 0 such that z = 2^k, if one exists; otherwise < 0 */ int mp_int_is_pow2(mp_int z); mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c); /* c = a^b (mod m) */ -mp_result mp_int_exptmod_evalue(mp_int a, int value, +mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c); /* c = a^v (mod m) */ -mp_result mp_int_exptmod_bvalue(int value, mp_int b, +mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c); /* c = v^b (mod m) */ mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, @@ -166,10 +173,14 @@ mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); /* c = gcd(a, b) */ mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, /* c = gcd(a, b) */ mp_int x, mp_int y); /* c = ax + by */ -mp_result mp_int_sqrt(mp_int a, mp_int c); /* c = floor(sqrt(q)) */ +mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c); /* c = lcm(a, b) */ -/* Convert to an int, if representable (returns MP_RANGE if not). */ -mp_result mp_int_to_int(mp_int z, int *out); +mp_result mp_int_root(mp_int a, mp_small b, mp_int c); /* c = floor(a^{1/b}) */ +#define mp_int_sqrt(a, c) mp_int_root(a, 2, c) /* c = floor(sqrt(a)) */ + +/* Convert to a small int, if representable; else MP_RANGE */ +mp_result mp_int_to_int(mp_int z, mp_small *out); +mp_result mp_int_to_uint(mp_int z, mp_usmall *out); /* Convert to nul-terminated string with the specified radix, writing at most limit characters including the nul terminator */ diff --git a/source4/heimdal/lib/hcrypto/imath/iprime.c b/source4/heimdal/lib/hcrypto/imath/iprime.c index 6313bab1b7..2bc9e7a6d1 100755..100644 --- a/source4/heimdal/lib/hcrypto/imath/iprime.c +++ b/source4/heimdal/lib/hcrypto/imath/iprime.c @@ -1,10 +1,10 @@ /* Name: iprime.c Purpose: Pseudoprimality testing routines - Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/> - Info: $Id: iprime.c 19737 2007-01-05 21:01:48Z lha $ + Author: M. J. Fromberger <http://spinning-yarns.org/michael/> + Info: $Id: iprime.c 635 2008-01-08 18:19:40Z sting $ - Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved. + Copyright (C) 2002-2008 Michael J. Fromberger, All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -47,7 +47,9 @@ static const int s_ptab[] = { 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, - 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, + 991, 997 +#ifdef IMATH_LARGE_PRIME_TABLE + , 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, @@ -110,10 +112,10 @@ static const int s_ptab[] = { 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999 +#endif }; static const int s_ptab_size = sizeof(s_ptab)/sizeof(s_ptab[0]); - /* {{{ mp_int_is_prime(z) */ /* Test whether z is likely to be prime: @@ -122,7 +124,8 @@ static const int s_ptab_size = sizeof(s_ptab)/sizeof(s_ptab[0]); */ mp_result mp_int_is_prime(mp_int z) { - int i, rem; + int i; + mp_small rem; mp_result res; /* First check for divisibility by small primes; this eliminates a diff --git a/source4/heimdal/lib/hcrypto/imath/iprime.h b/source4/heimdal/lib/hcrypto/imath/iprime.h index c935cdc111..6110dccb55 100755..100644 --- a/source4/heimdal/lib/hcrypto/imath/iprime.h +++ b/source4/heimdal/lib/hcrypto/imath/iprime.h @@ -1,10 +1,10 @@ /* Name: iprime.h Purpose: Pseudoprimality testing routines - Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/> - Info: $Id: iprime.h 18759 2006-10-21 16:32:36Z lha $ + Author: M. J. Fromberger <http://spinning-yarns.org/michael/> + Info: $Id: iprime.h 635 2008-01-08 18:19:40Z sting $ - Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved. + Copyright (C) 2002-2008 Michael J. Fromberger, All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files diff --git a/source4/heimdal/lib/hcrypto/md2.c b/source4/heimdal/lib/hcrypto/md2.c index 84b66c225f..8e4dd6169f 100644 --- a/source4/heimdal/lib/hcrypto/md2.c +++ b/source4/heimdal/lib/hcrypto/md2.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: md2.c 16480 2006-01-08 21:47:29Z lha $"); +RCSID("$Id$"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/hcrypto/md2.h b/source4/heimdal/lib/hcrypto/md2.h index cf3960b935..5fd832d5f0 100644 --- a/source4/heimdal/lib/hcrypto/md2.h +++ b/source4/heimdal/lib/hcrypto/md2.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: md2.h 16480 2006-01-08 21:47:29Z lha $ */ +/* $Id$ */ #ifndef HEIM_MD2_H #define HEIM_MD2_H 1 diff --git a/source4/heimdal/lib/hcrypto/md4.c b/source4/heimdal/lib/hcrypto/md4.c index 95ab340b48..dfdd78c849 100644 --- a/source4/heimdal/lib/hcrypto/md4.c +++ b/source4/heimdal/lib/hcrypto/md4.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: md4.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id$"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/hcrypto/md4.h b/source4/heimdal/lib/hcrypto/md4.h index 8725209d02..089c329a29 100644 --- a/source4/heimdal/lib/hcrypto/md4.h +++ b/source4/heimdal/lib/hcrypto/md4.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: md4.h 17450 2006-05-05 11:11:43Z lha $ */ +/* $Id$ */ #ifndef HEIM_MD4_H #define HEIM_MD4_H 1 diff --git a/source4/heimdal/lib/hcrypto/md5.c b/source4/heimdal/lib/hcrypto/md5.c index b145fd2ac7..d6149cdc73 100644 --- a/source4/heimdal/lib/hcrypto/md5.c +++ b/source4/heimdal/lib/hcrypto/md5.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: md5.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id$"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/hcrypto/md5.h b/source4/heimdal/lib/hcrypto/md5.h index de6bd3a0a6..0689113685 100644 --- a/source4/heimdal/lib/hcrypto/md5.h +++ b/source4/heimdal/lib/hcrypto/md5.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: md5.h 17450 2006-05-05 11:11:43Z lha $ */ +/* $Id$ */ #ifndef HEIM_MD5_H #define HEIM_MD5_H 1 diff --git a/source4/heimdal/lib/hcrypto/pkcs12.c b/source4/heimdal/lib/hcrypto/pkcs12.c index fcf04a73c1..2de482ccc8 100644 --- a/source4/heimdal/lib/hcrypto/pkcs12.c +++ b/source4/heimdal/lib/hcrypto/pkcs12.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: pkcs12.c 23137 2008-04-29 05:46:48Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/pkcs12.h b/source4/heimdal/lib/hcrypto/pkcs12.h index eb28b05467..71ee6ee49f 100644 --- a/source4/heimdal/lib/hcrypto/pkcs12.h +++ b/source4/heimdal/lib/hcrypto/pkcs12.h @@ -32,7 +32,7 @@ */ /* - * $Id: pkcs12.h 16564 2006-01-13 15:26:52Z lha $ + * $Id$ */ #ifndef _HEIM_PKCS12_H diff --git a/source4/heimdal/lib/hcrypto/pkcs5.c b/source4/heimdal/lib/hcrypto/pkcs5.c index 8a8f948abb..c44c76df5f 100644 --- a/source4/heimdal/lib/hcrypto/pkcs5.c +++ b/source4/heimdal/lib/hcrypto/pkcs5.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: pkcs5.c 23059 2008-04-18 13:04:08Z lha $"); +RCSID("$Id$"); #ifdef KRB5 #include <krb5-types.h> diff --git a/source4/heimdal/lib/hcrypto/rand-egd.c b/source4/heimdal/lib/hcrypto/rand-egd.c index c1f306bcc3..0ed06d83db 100644 --- a/source4/heimdal/lib/hcrypto/rand-egd.c +++ b/source4/heimdal/lib/hcrypto/rand-egd.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rand-egd.c 23461 2008-07-27 12:14:20Z lha $"); +RCSID("$Id$"); #include <sys/types.h> #ifdef HAVE_SYS_UN_H diff --git a/source4/heimdal/lib/hcrypto/rand-fortuna.c b/source4/heimdal/lib/hcrypto/rand-fortuna.c index da59a433b1..f75ba575cf 100644 --- a/source4/heimdal/lib/hcrypto/rand-fortuna.c +++ b/source4/heimdal/lib/hcrypto/rand-fortuna.c @@ -33,7 +33,7 @@ #include <config.h> #endif -RCSID("$Id: rand-fortuna.c 23463 2008-07-27 12:15:06Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/rand-unix.c b/source4/heimdal/lib/hcrypto/rand-unix.c index 5fb099d724..eaa81b0f1d 100644 --- a/source4/heimdal/lib/hcrypto/rand-unix.c +++ b/source4/heimdal/lib/hcrypto/rand-unix.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rand-unix.c 23462 2008-07-27 12:14:42Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/rand.c b/source4/heimdal/lib/hcrypto/rand.c index 1561f2ad39..4278300325 100644 --- a/source4/heimdal/lib/hcrypto/rand.c +++ b/source4/heimdal/lib/hcrypto/rand.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rand.c 23464 2008-07-27 12:15:21Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/rand.h b/source4/heimdal/lib/hcrypto/rand.h index c8ba2d9a7b..06e9ba4203 100644 --- a/source4/heimdal/lib/hcrypto/rand.h +++ b/source4/heimdal/lib/hcrypto/rand.h @@ -33,7 +33,7 @@ */ /* - * $Id: rand.h 20063 2007-01-30 18:30:36Z lha $ + * $Id$ */ #ifndef _HEIM_RAND_H diff --git a/source4/heimdal/lib/hcrypto/randi.h b/source4/heimdal/lib/hcrypto/randi.h index 6ae75f262b..7a5eb82c41 100644 --- a/source4/heimdal/lib/hcrypto/randi.h +++ b/source4/heimdal/lib/hcrypto/randi.h @@ -32,7 +32,7 @@ */ /* - * $Id: randi.h 21101 2007-06-18 03:53:46Z lha $ + * $Id$ */ #ifndef _HEIM_RANDI_H diff --git a/source4/heimdal/lib/hcrypto/rc2.c b/source4/heimdal/lib/hcrypto/rc2.c index 63992be9a9..e377ca7909 100644 --- a/source4/heimdal/lib/hcrypto/rc2.c +++ b/source4/heimdal/lib/hcrypto/rc2.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: rc2.c 17022 2006-04-09 17:03:21Z lha $"); +RCSID("$Id$"); #endif #include "rc2.h" diff --git a/source4/heimdal/lib/hcrypto/rc2.h b/source4/heimdal/lib/hcrypto/rc2.h index 5a2dd2d705..82b1e5eb3a 100644 --- a/source4/heimdal/lib/hcrypto/rc2.h +++ b/source4/heimdal/lib/hcrypto/rc2.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: rc2.h 16480 2006-01-08 21:47:29Z lha $ */ +/* $Id$ */ /* symbol renaming */ #define RC2_set_key hc_RC2_set_key diff --git a/source4/heimdal/lib/hcrypto/rc4.c b/source4/heimdal/lib/hcrypto/rc4.c index edaf37ddc4..7b97ab1947 100644 --- a/source4/heimdal/lib/hcrypto/rc4.c +++ b/source4/heimdal/lib/hcrypto/rc4.c @@ -36,7 +36,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: rc4.c 13640 2004-03-25 16:40:59Z lha $"); +RCSID("$Id$"); #endif #include <rc4.h> diff --git a/source4/heimdal/lib/hcrypto/rc4.h b/source4/heimdal/lib/hcrypto/rc4.h index 1ab25f59e6..c7cbc0df33 100644 --- a/source4/heimdal/lib/hcrypto/rc4.h +++ b/source4/heimdal/lib/hcrypto/rc4.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: rc4.h 16480 2006-01-08 21:47:29Z lha $ */ +/* $Id$ */ /* symbol renaming */ #define RC4_set_key hc_RC4_set_key diff --git a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c index c6330d27e4..57f13177df 100644 --- a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c +++ b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c @@ -31,7 +31,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: rijndael-alg-fst.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id$"); #endif #ifdef KRB5 diff --git a/source4/heimdal/lib/hcrypto/rnd_keys.c b/source4/heimdal/lib/hcrypto/rnd_keys.c index 0fd64af3b5..57dc7c373f 100644 --- a/source4/heimdal/lib/hcrypto/rnd_keys.c +++ b/source4/heimdal/lib/hcrypto/rnd_keys.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: rnd_keys.c 23093 2008-04-27 18:49:51Z lha $"); +RCSID("$Id$"); #endif #define HC_DEPRECATED diff --git a/source4/heimdal/lib/hcrypto/rsa-imath.c b/source4/heimdal/lib/hcrypto/rsa-imath.c index 74093ff7ba..4926a0c4e0 100644 --- a/source4/heimdal/lib/hcrypto/rsa-imath.c +++ b/source4/heimdal/lib/hcrypto/rsa-imath.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rsa-imath.c 21154 2007-06-18 21:58:12Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/rsa.c b/source4/heimdal/lib/hcrypto/rsa.c index 270857d175..da773a44b3 100644 --- a/source4/heimdal/lib/hcrypto/rsa.c +++ b/source4/heimdal/lib/hcrypto/rsa.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rsa.c 22422 2008-01-13 09:43:59Z lha $"); +RCSID("$Id$"); #include <stdio.h> #include <stdlib.h> diff --git a/source4/heimdal/lib/hcrypto/rsa.h b/source4/heimdal/lib/hcrypto/rsa.h index 0f54ca0a4d..3fa82fce7d 100644 --- a/source4/heimdal/lib/hcrypto/rsa.h +++ b/source4/heimdal/lib/hcrypto/rsa.h @@ -32,7 +32,7 @@ */ /* - * $Id: rsa.h 22269 2007-12-11 10:59:22Z lha $ + * $Id$ */ #ifndef _HEIM_RSA_H diff --git a/source4/heimdal/lib/hcrypto/sha.c b/source4/heimdal/lib/hcrypto/sha.c index a264f53f33..24b3e42f9b 100644 --- a/source4/heimdal/lib/hcrypto/sha.c +++ b/source4/heimdal/lib/hcrypto/sha.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: sha.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id$"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/hcrypto/sha.h b/source4/heimdal/lib/hcrypto/sha.h index 70fc20e222..50650f50fa 100644 --- a/source4/heimdal/lib/hcrypto/sha.h +++ b/source4/heimdal/lib/hcrypto/sha.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: sha.h 17450 2006-05-05 11:11:43Z lha $ */ +/* $Id$ */ #ifndef HEIM_SHA_H #define HEIM_SHA_H 1 diff --git a/source4/heimdal/lib/hcrypto/sha256.c b/source4/heimdal/lib/hcrypto/sha256.c index b95442eff6..ba662393a8 100644 --- a/source4/heimdal/lib/hcrypto/sha256.c +++ b/source4/heimdal/lib/hcrypto/sha256.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: sha256.c 17445 2006-05-05 10:37:46Z lha $"); +RCSID("$Id$"); #endif #include "hash.h" diff --git a/source4/heimdal/lib/hcrypto/ui.c b/source4/heimdal/lib/hcrypto/ui.c index 8c3ea1fa15..05f44bc669 100644 --- a/source4/heimdal/lib/hcrypto/ui.c +++ b/source4/heimdal/lib/hcrypto/ui.c @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: ui.c 23466 2008-07-27 12:16:15Z lha $"); +RCSID("$Id$"); #endif #include <stdio.h> diff --git a/source4/heimdal/lib/hcrypto/ui.h b/source4/heimdal/lib/hcrypto/ui.h index 53926cc1f7..f13f75c759 100644 --- a/source4/heimdal/lib/hcrypto/ui.h +++ b/source4/heimdal/lib/hcrypto/ui.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: ui.h 16480 2006-01-08 21:47:29Z lha $ */ +/* $Id$ */ #ifndef _HEIM_UI_H #define _HEIM_UI_H 1 |