Import libgcrypt 1.5.3.

This commit is contained in:
Vladimir Serbinenko 2013-11-07 06:35:50 +01:00
parent c12936c5d1
commit d1307d873a
72 changed files with 11732 additions and 2916 deletions

View file

@ -108,7 +108,7 @@ CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/g
CFLAGS_POSIX = -fno-builtin
CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap
CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers -Wno-redundant-decls $(CFLAGS_POSIX)
CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers -Wno-redundant-decls -Wno-undef $(CFLAGS_POSIX)
CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap $(CPPFLAGS_POSIX) -D_GCRYPT_IN_LIBGCRYPT=1 -I$(top_srcdir)/include/grub/gcrypt
CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime

View file

@ -6,6 +6,8 @@
#define __powerpc__ 1
#endif
#define GCRYPT_NO_DEPRECATED 1
/* Define to 1 to enable disk cache statistics. */
#define DISK_CACHE_STATS @DISK_CACHE_STATS@
#define BOOT_TIME_STATS @BOOT_TIME_STATS@

File diff suppressed because it is too large Load diff

View file

@ -35,7 +35,7 @@ libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES)
libcipher_la_LIBADD = $(GCRYPT_MODULES)
libcipher_la_SOURCES = \
cipher.c pubkey.c ac.c md.c \
cipher.c pubkey.c ac.c md.c kdf.c \
hmac-tests.c \
bithelp.h \
primegen.c \
@ -51,6 +51,7 @@ des.c \
dsa.c \
elgamal.c \
ecc.c \
idea.c \
md4.c \
md5.c \
rijndael.c rijndael-tables.h \
@ -68,7 +69,7 @@ rfc2268.c \
camellia.c camellia.h camellia-glue.c
if ENABLE_O_FLAG_MUNGING
o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g'
o_flag_munging = sed -e 's/-O\([2-9s][2-9s]*\)/-O1/' -e 's/-Ofast/-O1/g'
else
o_flag_munging = cat
endif

View file

@ -153,4 +153,3 @@ gcry_cipher_spec_t _gcry_cipher_spec_arcfour =
"ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context),
arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
};

View file

@ -1,6 +1,6 @@
/* cipher.c - cipher dispatcher
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
* 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
* 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@ -33,9 +33,12 @@
#define CTX_MAGIC_NORMAL 0x24091964
#define CTX_MAGIC_SECURE 0x46919042
/* Try to use 16 byte aligned cipher context for better performance.
We use the aligned attribute, thus it is only possible to implement
this with gcc. */
#undef NEED_16BYTE_ALIGNED_CONTEXT
#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
#define NEED_16BYTE_ALIGNED_CONTEXT 1
#if defined (__GNUC__)
# define NEED_16BYTE_ALIGNED_CONTEXT 1
#endif
/* A dummy extraspec so that we do not need to tests the extraspec
@ -108,6 +111,10 @@ static struct cipher_table_entry
&dummy_extra_spec, GCRY_CIPHER_CAMELLIA192 },
{ &_gcry_cipher_spec_camellia256,
&dummy_extra_spec, GCRY_CIPHER_CAMELLIA256 },
#endif
#ifdef USE_IDEA
{ &_gcry_cipher_spec_idea,
&dummy_extra_spec, GCRY_CIPHER_IDEA },
#endif
{ NULL }
};
@ -137,13 +144,14 @@ static int default_ciphers_registered;
while (0)
/* A VIA processor with the Padlock engine requires an alignment of
most data on a 16 byte boundary. Because we trick out the compiler
while allocating the context, the align attribute as used in
rijndael.c does not work on its own. Thus we need to make sure
that the entire context structure is a aligned on that boundary.
We achieve this by defining a new type and use that instead of our
usual alignment type. */
/* A VIA processor with the Padlock engine as well as the Intel AES_NI
instructions require an alignment of most data on a 16 byte
boundary. Because we trick out the compiler while allocating the
context, the align attribute as used in rijndael.c does not work on
its own. Thus we need to make sure that the entire context
structure is a aligned on that boundary. We achieve this by
defining a new type and use that instead of our usual alignment
type. */
typedef union
{
PROPERLY_ALIGNED_TYPE foo;
@ -186,6 +194,9 @@ struct gcry_cipher_handle
void (*cbc_dec)(void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks);
void (*ctr_enc)(void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks);
} bulk;
@ -197,19 +208,24 @@ struct gcry_cipher_handle
unsigned int iv:1; /* Set to 1 if a IV has been set. */
} marks;
/* The initialization vector. To help code optimization we make
sure that it is aligned on an unsigned long and u32 boundary. */
/* The initialization vector. For best performance we make sure
that it is properly aligned. In particular some implementations
of bulk operations expect an 16 byte aligned IV. */
union {
unsigned long dummy_iv;
u32 dummy_u32_iv;
cipher_context_alignment_t iv_align;
unsigned char iv[MAX_BLOCKSIZE];
} u_iv;
/* The counter for CTR mode. This field is also used by AESWRAP and
thus we can't use the U_IV union. */
union {
cipher_context_alignment_t iv_align;
unsigned char ctr[MAX_BLOCKSIZE];
} u_ctr;
/* Space to save an IV or CTR for chaining operations. */
unsigned char lastiv[MAX_BLOCKSIZE];
int unused; /* Number of unused bytes in the IV. */
unsigned char ctr[MAX_BLOCKSIZE]; /* For Counter (CTR) mode. */
int unused; /* Number of unused bytes in LASTIV. */
/* What follows are two contexts of the cipher in use. The first
one needs to be aligned well enough for the cipher operation
@ -598,10 +614,8 @@ check_cipher_algo (int algorithm)
}
/* Return the standard length of the key for the cipher algorithm with
the identifier ALGORITHM. This function expects a valid algorithm
and will abort if the algorithm is not available or the length of
the key is not known. */
/* Return the standard length in bits of the key for the cipher
algorithm with the identifier ALGORITHM. */
static unsigned int
cipher_get_keylen (int algorithm)
{
@ -619,17 +633,13 @@ cipher_get_keylen (int algorithm)
log_bug ("cipher %d w/o key length\n", algorithm);
_gcry_module_release (cipher);
}
else
log_bug ("cipher %d not found\n", algorithm);
ath_mutex_unlock (&ciphers_registered_lock);
return len;
}
/* Return the block length of the cipher algorithm with the identifier
ALGORITHM. This function expects a valid algorithm and will abort
if the algorithm is not available or the length of the key is not
known. */
ALGORITHM. This function return 0 for an invalid algorithm. */
static unsigned int
cipher_get_blocksize (int algorithm)
{
@ -647,8 +657,6 @@ cipher_get_blocksize (int algorithm)
log_bug ("cipher %d w/o blocksize\n", algorithm);
_gcry_module_release (cipher);
}
else
log_bug ("cipher %d not found\n", algorithm);
ath_mutex_unlock (&ciphers_registered_lock);
return len;
@ -774,7 +782,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
h = gcry_calloc (1, size);
if (! h)
err = gpg_err_code_from_errno (errno);
err = gpg_err_code_from_syserror ();
else
{
size_t off = 0;
@ -810,6 +818,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
h->bulk.cfb_dec = _gcry_aes_cfb_dec;
h->bulk.cbc_enc = _gcry_aes_cbc_enc;
h->bulk.cbc_dec = _gcry_aes_cbc_dec;
h->bulk.ctr_enc = _gcry_aes_ctr_enc;
break;
#endif /*USE_AES*/
@ -932,7 +941,7 @@ cipher_reset (gcry_cipher_hd_t c)
memset (&c->marks, 0, sizeof c->marks);
memset (c->u_iv.iv, 0, c->cipher->blocksize);
memset (c->lastiv, 0, c->cipher->blocksize);
memset (c->ctr, 0, c->cipher->blocksize);
memset (c->u_ctr.ctr, 0, c->cipher->blocksize);
}
@ -1437,35 +1446,72 @@ do_ctr_encrypt (gcry_cipher_hd_t c,
const unsigned char *inbuf, unsigned int inbuflen)
{
unsigned int n;
unsigned char tmp[MAX_BLOCKSIZE];
int i;
unsigned int blocksize = c->cipher->blocksize;
unsigned int nblocks;
if (outbuflen < inbuflen)
return GPG_ERR_BUFFER_TOO_SHORT;
if ((inbuflen % blocksize))
return GPG_ERR_INV_LENGTH;
for (n=0; n < inbuflen; n++)
/* First process a left over encrypted counter. */
if (c->unused)
{
if ((n % blocksize) == 0)
{
c->cipher->encrypt (&c->context.c, tmp, c->ctr);
for (i = blocksize; i > 0; i--)
{
c->ctr[i-1]++;
if (c->ctr[i-1] != 0)
break;
}
}
/* XOR input with encrypted counter and store in output. */
outbuf[n] = inbuf[n] ^ tmp[n % blocksize];
gcry_assert (c->unused < blocksize);
i = blocksize - c->unused;
for (n=0; c->unused && n < inbuflen; c->unused--, n++, i++)
{
/* XOR input with encrypted counter and store in output. */
outbuf[n] = inbuf[n] ^ c->lastiv[i];
}
inbuf += n;
outbuf += n;
inbuflen -= n;
}
/* Use a bulk method if available. */
nblocks = inbuflen / blocksize;
if (nblocks && c->bulk.ctr_enc)
{
c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
inbuf += nblocks * blocksize;
outbuf += nblocks * blocksize;
inbuflen -= nblocks * blocksize;
}
/* If we don't have a bulk method use the standard method. We also
use this method for the a remaining partial block. */
if (inbuflen)
{
unsigned char tmp[MAX_BLOCKSIZE];
for (n=0; n < inbuflen; n++)
{
if ((n % blocksize) == 0)
{
c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr);
for (i = blocksize; i > 0; i--)
{
c->u_ctr.ctr[i-1]++;
if (c->u_ctr.ctr[i-1] != 0)
break;
}
}
/* XOR input with encrypted counter and store in output. */
outbuf[n] = inbuf[n] ^ tmp[n % blocksize];
}
/* Save the unused bytes of the counter. */
n %= blocksize;
c->unused = (blocksize - n) % blocksize;
if (c->unused)
memcpy (c->lastiv+n, tmp+n, c->unused);
wipememory (tmp, sizeof tmp);
}
wipememory (tmp, sizeof tmp);
return 0;
}
@ -1513,7 +1559,7 @@ do_aeswrap_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
r = outbuf;
a = outbuf; /* We store A directly in OUTBUF. */
b = c->ctr; /* B is also used to concatenate stuff. */
b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
/* If an IV has been set we use that IV as the Alternative Initial
Value; if it has not been set we use the standard value. */
@ -1589,7 +1635,7 @@ do_aeswrap_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
r = outbuf;
a = c->lastiv; /* We use c->LASTIV as buffer for A. */
b = c->ctr; /* B is also used to concatenate stuff. */
b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
/* Copy the inbuf to the outbuf and save A. */
memcpy (a, inbuf, 8);
@ -1857,9 +1903,15 @@ gpg_error_t
_gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
{
if (ctr && ctrlen == hd->cipher->blocksize)
memcpy (hd->ctr, ctr, hd->cipher->blocksize);
{
memcpy (hd->u_ctr.ctr, ctr, hd->cipher->blocksize);
hd->unused = 0;
}
else if (!ctr || !ctrlen)
memset (hd->ctr, 0, hd->cipher->blocksize);
{
memset (hd->u_ctr.ctr, 0, hd->cipher->blocksize);
hd->unused = 0;
}
else
return gpg_error (GPG_ERR_INV_ARG);
return 0;
@ -1918,12 +1970,7 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
break;
case GCRYCTL_SET_CTR: /* Deprecated; use gcry_cipher_setctr. */
if (buffer && buflen == h->cipher->blocksize)
memcpy (h->ctr, buffer, h->cipher->blocksize);
else if (buffer == NULL || buflen == 0)
memset (h->ctr, 0, h->cipher->blocksize);
else
rc = GPG_ERR_INV_ARG;
rc = gpg_err_code (_gcry_cipher_setctr (h, buffer, buflen));
break;
case 61: /* Disable weak key detection (private). */
@ -2033,8 +2080,7 @@ gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
if ((ui > 0) && (ui <= 512))
*nbytes = (size_t) ui / 8;
else
/* The only reason is an invalid algo or a strange
blocksize. */
/* The only reason for an error is an invalid algo. */
err = GPG_ERR_CIPHER_ALGO;
}
break;

View file

@ -141,6 +141,11 @@ gen_k( gcry_mpi_t q )
unsigned int nbytes = (nbits+7)/8;
char *rndbuf = NULL;
/* To learn why we don't use mpi_mod to get the requested bit size,
read the paper: "The Insecurity of the Digital Signature
Algorithm with Partially Known Nonces" by Nguyen and Shparlinski.
Journal of Cryptology, New York. Vol 15, nr 3 (2003) */
if ( DBG_CIPHER )
log_debug("choosing a random k ");
for (;;)
@ -156,13 +161,20 @@ gen_k( gcry_mpi_t q )
else
{ /* Change only some of the higher bits. We could improve
this by directly requesting more memory at the first call
to get_random_bytes() and use this the here maybe it is
easier to do this directly in random.c. */
to get_random_bytes() and use these extra bytes here.
However the required management code is more complex and
thus we better use this simple method. */
char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
memcpy( rndbuf,pp, 4 );
gcry_free(pp);
}
_gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
/* Make sure we have the requested number of bits. This code
looks a bit funny but it is easy to understand if you
consider that mpi_set_highbit clears all higher bits. We
don't have a clear_highbit, thus we first set the high bit
and then clear it again. */
if ( mpi_test_bit( k, nbits-1 ) )
mpi_set_highbit( k, nbits-1 );
else
@ -1031,11 +1043,11 @@ static const char *
selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
{
static const char sample_data[] =
"(data (flags pkcs1)"
" (hash sha1 #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
"(data (flags raw)"
" (value #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
static const char sample_data_bad[] =
"(data (flags pkcs1)"
" (hash sha1 #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
"(data (flags raw)"
" (value #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
const char *errtxt = NULL;
gcry_error_t err;
@ -1179,4 +1191,3 @@ pk_extra_spec_t _gcry_pubkey_extraspec_dsa =
run_selftests,
dsa_generate_ext
};

View file

@ -1,5 +1,5 @@
/* ecc.c - Elliptic Curve Cryptography
Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc.
Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
This file is part of Libgcrypt.
@ -33,20 +33,21 @@
up. In fact there is not much left of the orginally code except for
some variable names and the text book implementaion of the sign and
verification algorithms. The arithmetic functions have entirely
been rewritten and moved to mpi/ec.c. */
been rewritten and moved to mpi/ec.c.
ECDH encrypt and decrypt code written by Andrey Jivsov,
*/
/* TODO:
- If we support point compression we need to decide how to compute
the keygrip - it should not change due to compression.
- If we support point compression we need to uncompress before
computing the keygrip
- In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
special case in mpi_powm or check whether mpi_mulm is faster.
- Decide whether we should hide the mpi_point_t definition.
- Support more than just ECDSA.
*/
@ -59,7 +60,6 @@
#include "mpi.h"
#include "cipher.h"
/* Definition of a curve. */
typedef struct
{
@ -68,6 +68,7 @@ typedef struct
gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */
mpi_point_t G; /* Base point (generator). */
gcry_mpi_t n; /* Order of G. */
const char *name; /* Name of curve or NULL. */
} elliptic_curve_t;
@ -120,11 +121,7 @@ static const struct
{ NULL, NULL}
};
/* This static table defines all available curves. */
static const struct
{
typedef struct {
const char *desc; /* Description of the curve. */
unsigned int nbits; /* Number of bits. */
unsigned int fips:1; /* True if this is a FIPS140-2 approved curve. */
@ -132,7 +129,10 @@ static const struct
const char *a, *b; /* The coefficients. */
const char *n; /* The order of the base point. */
const char *g_x, *g_y; /* Base point. */
} domain_parms[] =
} ecc_domain_parms_t;
/* This static table defines all available curves. */
static const ecc_domain_parms_t domain_parms[] =
{
{
"NIST P-192", 192, 1,
@ -369,7 +369,6 @@ curve_copy (elliptic_curve_t E)
}
/* Helper to scan a hex string. */
static gcry_mpi_t
scanval (const char *string)
@ -412,9 +411,6 @@ gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
}
/* Generate a random secret scalar k with an order of p
At the beginning this was identical to the code is in elgamal.c.
@ -428,7 +424,8 @@ gen_k (gcry_mpi_t p, int security_level)
nbits = mpi_get_nbits (p);
k = mpi_snew (nbits);
if (DBG_CIPHER)
log_debug ("choosing a random k of %u bits\n", nbits);
log_debug ("choosing a random k of %u bits at seclevel %d\n",
nbits, security_level);
gcry_mpi_randomize (k, nbits, security_level);
@ -437,23 +434,27 @@ gen_k (gcry_mpi_t p, int security_level)
return k;
}
/****************
* Generate the crypto system setup.
* As of now the fix NIST recommended values are used.
* The subgroup generator point is in another function: gen_big_point.
*/
/* Generate the crypto system setup. This function takes the NAME of
a curve or the desired number of bits and stores at R_CURVE the
parameters of the named curve or those of a suitable curve. The
chosen number of bits is stored on R_NBITS. */
static gpg_err_code_t
generate_curve (unsigned int nbits, const char *name,
elliptic_curve_t *curve, unsigned int *r_nbits)
fill_in_curve (unsigned int nbits, const char *name,
elliptic_curve_t *curve, unsigned int *r_nbits)
{
int idx, aliasno;
const char *resname = NULL; /* Set to a found curve name. */
if (name)
{
/* First check nor native curves. */
/* First check our native curves. */
for (idx = 0; domain_parms[idx].desc; idx++)
if (!strcmp (name, domain_parms[idx].desc))
break;
{
resname = domain_parms[idx].desc;
break;
}
/* If not found consult the alias table. */
if (!domain_parms[idx].desc)
{
@ -465,7 +466,10 @@ generate_curve (unsigned int nbits, const char *name,
for (idx = 0; domain_parms[idx].desc; idx++)
if (!strcmp (curve_aliases[aliasno].name,
domain_parms[idx].desc))
break;
{
resname = domain_parms[idx].desc;
break;
}
}
}
}
@ -484,7 +488,6 @@ generate_curve (unsigned int nbits, const char *name,
if (fips_mode () && !domain_parms[idx].fips )
return GPG_ERR_NOT_SUPPORTED;
*r_nbits = domain_parms[idx].nbits;
curve->p = scanval (domain_parms[idx].p);
curve->a = scanval (domain_parms[idx].a);
@ -493,6 +496,7 @@ generate_curve (unsigned int nbits, const char *name,
curve->G.x = scanval (domain_parms[idx].g_x);
curve->G.y = scanval (domain_parms[idx].g_y);
curve->G.z = mpi_alloc_set_ui (1);
curve->name = resname;
return 0;
}
@ -506,7 +510,8 @@ static gpg_err_code_t
generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
int transient_key,
gcry_mpi_t g_x, gcry_mpi_t g_y,
gcry_mpi_t q_x, gcry_mpi_t q_y)
gcry_mpi_t q_x, gcry_mpi_t q_y,
const char **r_usedcurve)
{
gpg_err_code_t err;
elliptic_curve_t E;
@ -515,25 +520,26 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
mpi_ec_t ctx;
gcry_random_level_t random_level;
err = generate_curve (nbits, name, &E, &nbits);
*r_usedcurve = NULL;
err = fill_in_curve (nbits, name, &E, &nbits);
if (err)
return err;
if (DBG_CIPHER)
{
log_mpidump ("ecc generation p", E.p);
log_mpidump ("ecc generation a", E.a);
log_mpidump ("ecc generation b", E.b);
log_mpidump ("ecc generation n", E.n);
log_mpidump ("ecc generation Gx", E.G.x);
log_mpidump ("ecc generation Gy", E.G.y);
log_mpidump ("ecc generation Gz", E.G.z);
log_mpidump ("ecgen curve p", E.p);
log_mpidump ("ecgen curve a", E.a);
log_mpidump ("ecgen curve b", E.b);
log_mpidump ("ecgen curve n", E.n);
log_mpidump ("ecgen curve Gx", E.G.x);
log_mpidump ("ecgen curve Gy", E.G.y);
log_mpidump ("ecgen curve Gz", E.G.z);
if (E.name)
log_debug ("ecgen curve used: %s\n", E.name);
}
random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
if (DBG_CIPHER)
log_debug ("choosing a random x of size %u%s\n", nbits,
transient_key? " (transient-key)":"");
d = gen_k (E.n, random_level);
/* Compute Q. */
@ -556,27 +562,29 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
if (g_x && g_y)
{
if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx))
log_fatal ("ecc generate: Failed to get affine coordinates\n");
log_fatal ("ecgen: Failed to get affine coordinates\n");
}
if (q_x && q_y)
{
if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx))
log_fatal ("ecc generate: Failed to get affine coordinates\n");
log_fatal ("ecgen: Failed to get affine coordinates\n");
}
_gcry_mpi_ec_free (ctx);
point_free (&Q);
mpi_free (d);
*r_usedcurve = E.name;
curve_free (&E);
/* Now we can test our keys (this should never fail!). */
/* Now we can test our keys (this should never fail!). */
test_keys (sk, nbits - 64);
return 0;
}
/****************
/*
* To verify correct skey it use a random information.
* First, encrypt and decrypt this dummy value,
* test if the information is recuperated.
@ -626,54 +634,56 @@ test_keys (ECC_secret_key *sk, unsigned int nbits)
mpi_free (test);
}
/****************
/*
* To check the validity of the value, recalculate the correspondence
* between the public value and the secret one.
*/
static int
check_secret_key (ECC_secret_key * sk)
{
int rc = 1;
mpi_point_t Q;
gcry_mpi_t y_2, y2 = mpi_alloc (0);
mpi_ec_t ctx;
gcry_mpi_t y_2, y2;
mpi_ec_t ctx = NULL;
point_init (&Q);
/* ?primarity test of 'p' */
/* (...) //!! */
/* G in E(F_p) */
y_2 = gen_y_2 (sk->E.G.x, &sk->E); /* y^2=x^3+a*x+b */
y2 = mpi_alloc (0);
mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p); /* y^2=y*y */
if (mpi_cmp (y_2, y2))
{
if (DBG_CIPHER)
log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
return (1);
goto leave;
}
/* G != PaI */
if (!mpi_cmp_ui (sk->E.G.z, 0))
{
if (DBG_CIPHER)
log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
return (1);
goto leave;
}
point_init (&Q);
ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a);
_gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
if (mpi_cmp_ui (Q.z, 0))
{
if (DBG_CIPHER)
log_debug ("check_secret_key: E is not a curve of order n\n");
point_free (&Q);
_gcry_mpi_ec_free (ctx);
return 1;
goto leave;
}
/* pubkey cannot be PaI */
if (!mpi_cmp_ui (sk->Q.z, 0))
{
if (DBG_CIPHER)
log_debug ("Bad check: Q can not be a Point at Infinity!\n");
_gcry_mpi_ec_free (ctx);
return (1);
goto leave;
}
/* pubkey = [d]G over E */
_gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
@ -682,12 +692,16 @@ check_secret_key (ECC_secret_key * sk)
if (DBG_CIPHER)
log_debug
("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
_gcry_mpi_ec_free (ctx);
return (1);
goto leave;
}
rc = 0; /* Okay. */
leave:
_gcry_mpi_ec_free (ctx);
mpi_free (y2);
mpi_free (y_2);
point_free (&Q);
return 0;
return rc;
}
@ -703,6 +717,9 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
mpi_point_t I;
mpi_ec_t ctx;
if (DBG_CIPHER)
log_mpidump ("ecdsa sign hash ", input );
k = NULL;
dr = mpi_alloc (0);
sum = mpi_alloc (0);
@ -741,6 +758,12 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */
}
if (DBG_CIPHER)
{
log_mpidump ("ecdsa sign result r ", r);
log_mpidump ("ecdsa sign result s ", s);
}
leave:
_gcry_mpi_ec_free (ctx);
point_free (&I);
@ -753,6 +776,7 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
return err;
}
/*
* Check if R and S verifies INPUT.
*/
@ -824,10 +848,10 @@ verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
{
if (DBG_CIPHER)
{
log_mpidump (" x", x);
log_mpidump (" y", y);
log_mpidump (" r", r);
log_mpidump (" s", s);
log_mpidump (" x", x);
log_mpidump (" y", y);
log_mpidump (" r", r);
log_mpidump (" s", s);
log_debug ("ecc verify: Not verified\n");
}
err = GPG_ERR_BAD_SIGNATURE;
@ -850,7 +874,7 @@ verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
}
/*********************************************
************** interface ******************
*********************************************/
@ -889,12 +913,10 @@ ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p)
log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
gcry_free (buf);
mpi_free (x);
mpi_free (y);
return result;
}
/* RESULT must have been initialized and is set on success to the
point given by VALUE. */
static gcry_error_t
@ -967,10 +989,10 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
char *curve_name = NULL;
gcry_sexp_t l1;
int transient_key = 0;
const char *usedcurve = NULL;
(void)algo;
(void)evalue;
(void)r_extrainfo;
if (genparms)
{
@ -1001,28 +1023,45 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
g_y = mpi_new (0);
q_x = mpi_new (0);
q_y = mpi_new (0);
ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y);
ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y,
&usedcurve);
gcry_free (curve_name);
if (ec)
return ec;
if (usedcurve) /* Fixme: No error return checking. */
gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", usedcurve);
skey[0] = sk.E.p;
skey[1] = sk.E.a;
skey[2] = sk.E.b;
/* The function ec2os releases g_x and g_y. */
skey[3] = ec2os (g_x, g_y, sk.E.p);
skey[4] = sk.E.n;
/* The function ec2os releases g_x and g_y. */
skey[5] = ec2os (q_x, q_y, sk.E.p);
skey[6] = sk.d;
mpi_free (g_x);
mpi_free (g_y);
mpi_free (q_x);
mpi_free (q_y);
point_free (&sk.E.G);
point_free (&sk.Q);
/* Make an empty list of factors. */
*retfactors = gcry_calloc ( 1, sizeof **retfactors );
if (!*retfactors)
return gpg_err_code_from_syserror ();
return gpg_err_code_from_syserror (); /* Fixme: relase mem? */
if (DBG_CIPHER)
{
log_mpidump ("ecgen result p", skey[0]);
log_mpidump ("ecgen result a", skey[1]);
log_mpidump ("ecgen result b", skey[2]);
log_mpidump ("ecgen result G", skey[3]);
log_mpidump ("ecgen result n", skey[4]);
log_mpidump ("ecgen result Q", skey[5]);
log_mpidump ("ecgen result d", skey[6]);
}
return 0;
}
@ -1037,7 +1076,7 @@ ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
}
/* Return the parameters of the curve NAME. */
/* Return the parameters of the curve NAME in an MPI array. */
static gcry_err_code_t
ecc_get_param (const char *name, gcry_mpi_t *pkey)
{
@ -1047,7 +1086,7 @@ ecc_get_param (const char *name, gcry_mpi_t *pkey)
mpi_ec_t ctx;
gcry_mpi_t g_x, g_y;
err = generate_curve (0, name, &E, &nbits);
err = fill_in_curve (0, name, &E, &nbits);
if (err)
return err;
@ -1066,10 +1105,120 @@ ecc_get_param (const char *name, gcry_mpi_t *pkey)
pkey[4] = E.n;
pkey[5] = NULL;
mpi_free (g_x);
mpi_free (g_y);
return 0;
}
/* Return the parameters of the curve NAME as an S-expression. */
static gcry_sexp_t
ecc_get_param_sexp (const char *name)
{
gcry_mpi_t pkey[6];
gcry_sexp_t result;
int i;
if (ecc_get_param (name, pkey))
return NULL;
if (gcry_sexp_build (&result, NULL,
"(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))",
pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]))
result = NULL;
for (i=0; pkey[i]; i++)
gcry_mpi_release (pkey[i]);
return result;
}
/* Return the name matching the parameters in PKEY. */
static const char *
ecc_get_curve (gcry_mpi_t *pkey, int iterator, unsigned int *r_nbits)
{
gpg_err_code_t err;
elliptic_curve_t E;
int idx;
gcry_mpi_t tmp;
const char *result = NULL;
if (r_nbits)
*r_nbits = 0;
if (!pkey)
{
idx = iterator;
if (idx >= 0 && idx < DIM (domain_parms))
{
result = domain_parms[idx].desc;
if (r_nbits)
*r_nbits = domain_parms[idx].nbits;
}
return result;
}
if (!pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4])
return NULL;
E.p = pkey[0];
E.a = pkey[1];
E.b = pkey[2];
point_init (&E.G);
err = os2ec (&E.G, pkey[3]);
if (err)
{
point_free (&E.G);
return NULL;
}
E.n = pkey[4];
for (idx = 0; domain_parms[idx].desc; idx++)
{
tmp = scanval (domain_parms[idx].p);
if (!mpi_cmp (tmp, E.p))
{
mpi_free (tmp);
tmp = scanval (domain_parms[idx].a);
if (!mpi_cmp (tmp, E.a))
{
mpi_free (tmp);
tmp = scanval (domain_parms[idx].b);
if (!mpi_cmp (tmp, E.b))
{
mpi_free (tmp);
tmp = scanval (domain_parms[idx].n);
if (!mpi_cmp (tmp, E.n))
{
mpi_free (tmp);
tmp = scanval (domain_parms[idx].g_x);
if (!mpi_cmp (tmp, E.G.x))
{
mpi_free (tmp);
tmp = scanval (domain_parms[idx].g_y);
if (!mpi_cmp (tmp, E.G.y))
{
result = domain_parms[idx].desc;
if (r_nbits)
*r_nbits = domain_parms[idx].nbits;
break;
}
}
}
}
}
}
mpi_free (tmp);
}
point_free (&E.G);
return result;
}
static gcry_err_code_t
ecc_check_secret_key (int algo, gcry_mpi_t *skey)
{
@ -1078,8 +1227,9 @@ ecc_check_secret_key (int algo, gcry_mpi_t *skey)
(void)algo;
/* FIXME: This check looks a bit fishy: Now long is the array? */
if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
|| !skey[6] || !skey[7] || !skey[8] || !skey[9] || !skey[10])
|| !skey[6])
return GPG_ERR_BAD_MPI;
sk.E.p = skey[0];
@ -1163,6 +1313,7 @@ ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
return err;
}
static gcry_err_code_t
ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
int (*cmp)(void *, gcry_mpi_t), void *opaquev)
@ -1206,6 +1357,221 @@ ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
}
/* ecdh raw is classic 2-round DH protocol published in 1976.
*
* Overview of ecc_encrypt_raw and ecc_decrypt_raw.
*
* As with any PK operation, encrypt version uses a public key and
* decrypt -- private.
*
* Symbols used below:
* G - field generator point
* d - private long-term scalar
* dG - public long-term key
* k - ephemeral scalar
* kG - ephemeral public key
* dkG - shared secret
*
* ecc_encrypt_raw description:
* input:
* data[0] : private scalar (k)
* output:
* result[0] : shared point (kdG)
* result[1] : generated ephemeral public key (kG)
*
* ecc_decrypt_raw description:
* input:
* data[0] : a point kG (ephemeral public key)
* output:
* result[0] : shared point (kdG)
*/
static gcry_err_code_t
ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k,
gcry_mpi_t *pkey, int flags)
{
ECC_public_key pk;
mpi_ec_t ctx;
gcry_mpi_t result[2];
int err;
(void)algo;
(void)flags;
if (!k
|| !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
return GPG_ERR_BAD_MPI;
pk.E.p = pkey[0];
pk.E.a = pkey[1];
pk.E.b = pkey[2];
point_init (&pk.E.G);
err = os2ec (&pk.E.G, pkey[3]);
if (err)
{
point_free (&pk.E.G);
return err;
}
pk.E.n = pkey[4];
point_init (&pk.Q);
err = os2ec (&pk.Q, pkey[5]);
if (err)
{
point_free (&pk.E.G);
point_free (&pk.Q);
return err;
}
ctx = _gcry_mpi_ec_init (pk.E.p, pk.E.a);
/* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
{
mpi_point_t R; /* Result that we return. */
gcry_mpi_t x, y;
x = mpi_new (0);
y = mpi_new (0);
point_init (&R);
/* R = kQ <=> R = kdG */
_gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
result[0] = ec2os (x, y, pk.E.p);
/* R = kG */
_gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
result[1] = ec2os (x, y, pk.E.p);
mpi_free (x);
mpi_free (y);
point_free (&R);
}
_gcry_mpi_ec_free (ctx);
point_free (&pk.E.G);
point_free (&pk.Q);
if (!result[0] || !result[1])
{
mpi_free (result[0]);
mpi_free (result[1]);
return GPG_ERR_ENOMEM;
}
/* Success. */
resarr[0] = result[0];
resarr[1] = result[1];
return 0;
}
/* input:
* data[0] : a point kG (ephemeral public key)
* output:
* resaddr[0] : shared point kdG
*
* see ecc_encrypt_raw for details.
*/
static gcry_err_code_t
ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
gcry_mpi_t *skey, int flags)
{
ECC_secret_key sk;
mpi_point_t R; /* Result that we return. */
mpi_point_t kG;
mpi_ec_t ctx;
gcry_mpi_t r;
int err;
(void)algo;
(void)flags;
*result = NULL;
if (!data || !data[0]
|| !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
|| !skey[5] || !skey[6] )
return GPG_ERR_BAD_MPI;
point_init (&kG);
err = os2ec (&kG, data[0]);
if (err)
{
point_free (&kG);
return err;
}
sk.E.p = skey[0];
sk.E.a = skey[1];
sk.E.b = skey[2];
point_init (&sk.E.G);
err = os2ec (&sk.E.G, skey[3]);
if (err)
{
point_free (&kG);
point_free (&sk.E.G);
return err;
}
sk.E.n = skey[4];
point_init (&sk.Q);
err = os2ec (&sk.Q, skey[5]);
if (err)
{
point_free (&kG);
point_free (&sk.E.G);
point_free (&sk.Q);
return err;
}
sk.d = skey[6];
ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a);
/* R = dkG */
point_init (&R);
_gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
point_free (&kG);
/* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so: */
{
gcry_mpi_t x, y;
x = mpi_new (0);
y = mpi_new (0);
if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
log_fatal ("ecdh: Failed to get affine coordinates\n");
r = ec2os (x, y, sk.E.p);
mpi_free (x);
mpi_free (y);
}
point_free (&R);
_gcry_mpi_ec_free (ctx);
point_free (&kG);
point_free (&sk.E.G);
point_free (&sk.Q);
if (!r)
return GPG_ERR_ENOMEM;
/* Success. */
*result = r;
return 0;
}
static unsigned int
ecc_get_nbits (int algo, gcry_mpi_t *pkey)
@ -1216,23 +1582,23 @@ ecc_get_nbits (int algo, gcry_mpi_t *pkey)
}
/* See rsa.c for a description of this function. */
static gpg_err_code_t
compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
{
static const char names[] = "pabgnq";
#define N_COMPONENTS 6
static const char names[N_COMPONENTS+1] = "pabgnq";
gpg_err_code_t ec = 0;
gcry_sexp_t l1;
gcry_mpi_t values[6];
gcry_mpi_t values[N_COMPONENTS];
int idx;
/* Clear the values for easier error cleanup. */
for (idx=0; idx < 6; idx++)
for (idx=0; idx < N_COMPONENTS; idx++)
values[idx] = NULL;
/* Fill values with all available parameters. */
for (idx=0; idx < 6; idx++)
/* Fill values with all provided parameters. */
for (idx=0; idx < N_COMPONENTS; idx++)
{
l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
if (l1)
@ -1253,12 +1619,13 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
if (l1)
{
char *curve;
gcry_mpi_t tmpvalues[6];
gcry_mpi_t tmpvalues[N_COMPONENTS];
for (idx = 0; idx < 6; idx++)
for (idx = 0; idx < N_COMPONENTS; idx++)
tmpvalues[idx] = NULL;
curve = _gcry_sexp_nth_string (l1, 1);
gcry_sexp_release (l1);
if (!curve)
{
ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
@ -1269,7 +1636,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
if (ec)
goto leave;
for (idx = 0; idx < 6; idx++)
for (idx = 0; idx < N_COMPONENTS; idx++)
{
if (!values[idx])
values[idx] = tmpvalues[idx];
@ -1281,7 +1648,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
/* Check that all parameters are known and normalize all MPIs (that
should not be required but we use an internal function later and
thus we better make 100% sure that they are normalized). */
for (idx = 0; idx < 6; idx++)
for (idx = 0; idx < N_COMPONENTS; idx++)
if (!values[idx])
{
ec = GPG_ERR_NO_OBJ;
@ -1291,7 +1658,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
_gcry_mpi_normalize (values[idx]);
/* Hash them all. */
for (idx = 0; idx < 6; idx++)
for (idx = 0; idx < N_COMPONENTS; idx++)
{
char buf[30];
unsigned char *rawmpi;
@ -1311,10 +1678,11 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
}
leave:
for (idx = 0; idx < 6; idx++)
for (idx = 0; idx < N_COMPONENTS; idx++)
_gcry_mpi_release (values[idx]);
return ec;
#undef N_COMPONENTS
}
@ -1378,6 +1746,12 @@ static const char *ecdsa_names[] =
"ecc",
NULL,
};
static const char *ecdh_names[] =
{
"ecdh",
"ecc",
NULL,
};
gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
{
@ -1393,11 +1767,27 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
ecc_get_nbits
};
gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
{
"ECDH", ecdh_names,
"pabgnq", "pabgnqd", "se", "", "pabgnq",
GCRY_PK_USAGE_ENCR,
ecc_generate,
ecc_check_secret_key,
ecc_encrypt_raw,
ecc_decrypt_raw,
NULL,
NULL,
ecc_get_nbits
};
pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa =
{
run_selftests,
ecc_generate_ext,
compute_keygrip,
ecc_get_param
ecc_get_param,
ecc_get_curve,
ecc_get_param_sexp
};

View file

@ -843,4 +843,3 @@ pk_extra_spec_t _gcry_pubkey_extraspec_elg =
elg_generate_ext,
NULL
};

View file

@ -91,4 +91,3 @@ _gcry_hash_selftest_check_one (int algo,
return result;
}

View file

@ -0,0 +1,378 @@
/* idea.c - IDEA function
* Copyright 1997, 1998, 1999, 2001 Werner Koch (dd9jn)
* Copyright 2013 g10 Code GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* WERNER KOCH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Werner Koch shall not be
* used in advertising or otherwise to promote the sale, use or other dealings
* in this Software without prior written authorization from Werner Koch.
*
* Patents on IDEA have expired:
* Europe: EP0482154 on 2011-05-16,
* Japan: JP3225440 on 2011-05-16,
* U.S.: 5,214,703 on 2012-01-07.
*/
/*
* Please see http://www.noepatents.org/ to learn why software patents
* are bad for society and what you can do to fight them.
*
* The code herein is based on the one from:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
* ISBN 0-471-11709-9.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "types.h" /* for byte and u32 typedefs */
#include "g10lib.h"
#include "cipher.h"
#define IDEA_KEYSIZE 16
#define IDEA_BLOCKSIZE 8
#define IDEA_ROUNDS 8
#define IDEA_KEYLEN (6*IDEA_ROUNDS+4)
typedef struct {
u16 ek[IDEA_KEYLEN];
u16 dk[IDEA_KEYLEN];
int have_dk;
} IDEA_context;
static const char *selftest(void);
static u16
mul_inv( u16 x )
{
u16 t0, t1;
u16 q, y;
if( x < 2 )
return x;
t1 = 0x10001L / x;
y = 0x10001L % x;
if( y == 1 )
return (1-t1) & 0xffff;
t0 = 1;
do {
q = x / y;
x = x % y;
t0 += q * t1;
if( x == 1 )
return t0;
q = y / x;
y = y % x;
t1 += q * t0;
} while( y != 1 );
return (1-t1) & 0xffff;
}
static void
expand_key( const byte *userkey, u16 *ek )
{
int i,j;
for(j=0; j < 8; j++ ) {
ek[j] = (*userkey << 8) + userkey[1];
userkey += 2;
}
for(i=0; j < IDEA_KEYLEN; j++ ) {
i++;
ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
ek += i & 8;
i &= 7;
}
}
static void
invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] )
{
int i;
u16 t1, t2, t3;
u16 temp[IDEA_KEYLEN];
u16 *p = temp + IDEA_KEYLEN;
t1 = mul_inv( *ek++ );
t2 = -*ek++;
t3 = -*ek++;
*--p = mul_inv( *ek++ );
*--p = t3;
*--p = t2;
*--p = t1;
for(i=0; i < IDEA_ROUNDS-1; i++ ) {
t1 = *ek++;
*--p = *ek++;
*--p = t1;
t1 = mul_inv( *ek++ );
t2 = -*ek++;
t3 = -*ek++;
*--p = mul_inv( *ek++ );
*--p = t2;
*--p = t3;
*--p = t1;
}
t1 = *ek++;
*--p = *ek++;
*--p = t1;
t1 = mul_inv( *ek++ );
t2 = -*ek++;
t3 = -*ek++;
*--p = mul_inv( *ek++ );
*--p = t3;
*--p = t2;
*--p = t1;
memcpy(dk, temp, sizeof(temp) );
memset(temp, 0, sizeof(temp) ); /* burn temp */
}
static void
cipher( byte *outbuf, const byte *inbuf, u16 *key )
{
u16 s2, s3;
u16 in[4];
int r = IDEA_ROUNDS;
#define x1 (in[0])
#define x2 (in[1])
#define x3 (in[2])
#define x4 (in[3])
#define MUL(x,y) \
do {u16 _t16; u32 _t32; \
if( (_t16 = (y)) ) { \
if( (x = (x)&0xffff) ) { \
_t32 = (u32)x * _t16; \
x = _t32 & 0xffff; \
_t16 = _t32 >> 16; \
x = ((x)-_t16) + (x<_t16?1:0); \
} \
else { \
x = 1 - _t16; \
} \
} \
else { \
x = 1 - x; \
} \
} while(0)
memcpy (in, inbuf, sizeof in);
#ifndef WORDS_BIGENDIAN
x1 = (x1>>8) | (x1<<8);
x2 = (x2>>8) | (x2<<8);
x3 = (x3>>8) | (x3<<8);
x4 = (x4>>8) | (x4<<8);
#endif
do {
MUL(x1, *key++);
x2 += *key++;
x3 += *key++;
MUL(x4, *key++ );
s3 = x3;
x3 ^= x1;
MUL(x3, *key++);
s2 = x2;
x2 ^=x4;
x2 += x3;
MUL(x2, *key++);
x3 += x2;
x1 ^= x2;
x4 ^= x3;
x2 ^= s3;
x3 ^= s2;
} while( --r );
MUL(x1, *key++);
x3 += *key++;
x2 += *key++;
MUL(x4, *key);
#ifndef WORDS_BIGENDIAN
x1 = (x1>>8) | (x1<<8);
x2 = (x2>>8) | (x2<<8);
x3 = (x3>>8) | (x3<<8);
x4 = (x4>>8) | (x4<<8);
#endif
memcpy (outbuf+0, &x1, 2);
memcpy (outbuf+2, &x3, 2);
memcpy (outbuf+4, &x2, 2);
memcpy (outbuf+6, &x4, 2);
#undef MUL
#undef x1
#undef x2
#undef x3
#undef x4
}
static int
do_setkey( IDEA_context *c, const byte *key, unsigned int keylen )
{
static int initialized = 0;
static const char *selftest_failed = 0;
if( !initialized ) {
initialized = 1;
selftest_failed = selftest();
if( selftest_failed )
log_error( "%s\n", selftest_failed );
}
if( selftest_failed )
return GPG_ERR_SELFTEST_FAILED;
assert(keylen == 16);
c->have_dk = 0;
expand_key( key, c->ek );
invert_key( c->ek, c->dk );
return 0;
}
static gcry_err_code_t
idea_setkey (void *context, const byte *key, unsigned int keylen)
{
IDEA_context *ctx = context;
int rc = do_setkey (ctx, key, keylen);
_gcry_burn_stack (23+6*sizeof(void*));
return rc;
}
static void
encrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf )
{
cipher( outbuf, inbuf, c->ek );
}
static void
idea_encrypt (void *context, byte *out, const byte *in)
{
IDEA_context *ctx = context;
encrypt_block (ctx, out, in);
_gcry_burn_stack (24+3*sizeof (void*));
}
static void
decrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf )
{
if( !c->have_dk ) {
c->have_dk = 1;
invert_key( c->ek, c->dk );
}
cipher( outbuf, inbuf, c->dk );
}
static void
idea_decrypt (void *context, byte *out, const byte *in)
{
IDEA_context *ctx = context;
decrypt_block (ctx, out, in);
_gcry_burn_stack (24+3*sizeof (void*));
}
static const char *
selftest( void )
{
static struct {
byte key[16];
byte plain[8];
byte cipher[8];
} test_vectors[] = {
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 },
{ 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x54, 0x0E, 0x5F, 0xEA, 0x18, 0xC2, 0xF8, 0xB1 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x00, 0x19, 0x32, 0x4B, 0x64, 0x7D, 0x96, 0xAF },
{ 0x9F, 0x0A, 0x0A, 0xB6, 0xE1, 0x0C, 0xED, 0x78 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0xF5, 0x20, 0x2D, 0x5B, 0x9C, 0x67, 0x1B, 0x08 },
{ 0xCF, 0x18, 0xFD, 0x73, 0x55, 0xE2, 0xC5, 0xC5 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0xFA, 0xE6, 0xD2, 0xBE, 0xAA, 0x96, 0x82, 0x6E },
{ 0x85, 0xDF, 0x52, 0x00, 0x56, 0x08, 0x19, 0x3D } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50 },
{ 0x2F, 0x7D, 0xE7, 0x50, 0x21, 0x2F, 0xB7, 0x34 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x05, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x23, 0x28 },
{ 0x7B, 0x73, 0x14, 0x92, 0x5D, 0xE5, 0x9C, 0x09 } },
{ { 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14,
0x00, 0x19, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x28 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x3E, 0xC0, 0x47, 0x80, 0xBE, 0xFF, 0x6E, 0x20 } },
{ { 0x3A, 0x98, 0x4E, 0x20, 0x00, 0x19, 0x5D, 0xB3,
0x2E, 0xE5, 0x01, 0xC8, 0xC4, 0x7C, 0xEA, 0x60 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x97, 0xBC, 0xD8, 0x20, 0x07, 0x80, 0xDA, 0x86 } },
{ { 0x00, 0x64, 0x00, 0xC8, 0x01, 0x2C, 0x01, 0x90,
0x01, 0xF4, 0x02, 0x58, 0x02, 0xBC, 0x03, 0x20 },
{ 0x05, 0x32, 0x0A, 0x64, 0x14, 0xC8, 0x19, 0xFA },
{ 0x65, 0xBE, 0x87, 0xE7, 0xA2, 0x53, 0x8A, 0xED } },
{ { 0x9D, 0x40, 0x75, 0xC1, 0x03, 0xBC, 0x32, 0x2A,
0xFB, 0x03, 0xE7, 0xBE, 0x6A, 0xB3, 0x00, 0x06 },
{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 },
{ 0xF5, 0xDB, 0x1A, 0xC4, 0x5E, 0x5E, 0xF9, 0xF9 } }
};
IDEA_context c;
byte buffer[8];
int i;
for(i=0; i < DIM(test_vectors); i++ ) {
do_setkey( &c, test_vectors[i].key, 16 );
encrypt_block( &c, buffer, test_vectors[i].plain );
if( memcmp( buffer, test_vectors[i].cipher, 8 ) )
return "IDEA test encryption failed.";
decrypt_block( &c, buffer, test_vectors[i].cipher );
if( memcmp( buffer, test_vectors[i].plain, 8 ) )
return "IDEA test decryption failed.";
}
return NULL;
}
gcry_cipher_spec_t _gcry_cipher_spec_idea =
{
"IDEA", NULL, NULL, IDEA_BLOCKSIZE, 128,
sizeof (IDEA_context),
idea_setkey, idea_encrypt, idea_decrypt
};

View file

@ -0,0 +1,278 @@
/* kdf.c - Key Derivation Functions
* Copyright (C) 1998, 2011 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "g10lib.h"
#include "cipher.h"
#include "ath.h"
/* Transform a passphrase into a suitable key of length KEYSIZE and
store this key in the caller provided buffer KEYBUFFER. The caller
must provide an HASHALGO, a valid ALGO and depending on that algo a
SALT of 8 bytes and the number of ITERATIONS. Code taken from
gnupg/agent/protect.c:hash_passphrase. */
gpg_err_code_t
openpgp_s2k (const void *passphrase, size_t passphraselen,
int algo, int hashalgo,
const void *salt, size_t saltlen,
unsigned long iterations,
size_t keysize, void *keybuffer)
{
gpg_err_code_t ec;
gcry_md_hd_t md;
char *key = keybuffer;
int pass, i;
int used = 0;
int secmode;
if ((algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K)
&& (!salt || saltlen != 8))
return GPG_ERR_INV_VALUE;
secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer);
ec = gpg_err_code (gcry_md_open (&md, hashalgo,
secmode? GCRY_MD_FLAG_SECURE : 0));
if (ec)
return ec;
for (pass=0; used < keysize; pass++)
{
if (pass)
{
gcry_md_reset (md);
for (i=0; i < pass; i++) /* Preset the hash context. */
gcry_md_putc (md, 0);
}
if (algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K)
{
int len2 = passphraselen + 8;
unsigned long count = len2;
if (algo == GCRY_KDF_ITERSALTED_S2K)
{
count = iterations;
if (count < len2)
count = len2;
}
while (count > len2)
{
gcry_md_write (md, salt, saltlen);
gcry_md_write (md, passphrase, passphraselen);
count -= len2;
}
if (count < saltlen)
gcry_md_write (md, salt, count);
else
{
gcry_md_write (md, salt, saltlen);
count -= saltlen;
gcry_md_write (md, passphrase, count);
}
}
else
gcry_md_write (md, passphrase, passphraselen);
gcry_md_final (md);
i = gcry_md_get_algo_dlen (hashalgo);
if (i > keysize - used)
i = keysize - used;
memcpy (key+used, gcry_md_read (md, hashalgo), i);
used += i;
}
gcry_md_close (md);
return 0;
}
/* Transform a passphrase into a suitable key of length KEYSIZE and
store this key in the caller provided buffer KEYBUFFER. The caller
must provide PRFALGO which indicates the pseudorandom function to
use: This shall be the algorithms id of a hash algorithm; it is
used in HMAC mode. SALT is a salt of length SALTLEN and ITERATIONS
gives the number of iterations. */
gpg_err_code_t
pkdf2 (const void *passphrase, size_t passphraselen,
int hashalgo,
const void *salt, size_t saltlen,
unsigned long iterations,
size_t keysize, void *keybuffer)
{
gpg_err_code_t ec;
gcry_md_hd_t md;
int secmode;
unsigned int dklen = keysize;
char *dk = keybuffer;
unsigned int hlen; /* Output length of the digest function. */
unsigned int l; /* Rounded up number of blocks. */
unsigned int r; /* Number of octets in the last block. */
char *sbuf; /* Malloced buffer to concatenate salt and iter
as well as space to hold TBUF and UBUF. */
char *tbuf; /* Buffer for T; ptr into SBUF, size is HLEN. */
char *ubuf; /* Buffer for U; ptr into SBUF, size is HLEN. */
unsigned int lidx; /* Current block number. */
unsigned long iter; /* Current iteration number. */
unsigned int i;
if (!salt || !saltlen || !iterations || !dklen)
return GPG_ERR_INV_VALUE;
hlen = gcry_md_get_algo_dlen (hashalgo);
if (!hlen)
return GPG_ERR_DIGEST_ALGO;
secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer);
/* We ignore step 1 from pksc5v2.1 which demands a check that dklen
is not larger that 0xffffffff * hlen. */
/* Step 2 */
l = ((dklen - 1)/ hlen) + 1;
r = dklen - (l - 1) * hlen;
/* Setup buffers and prepare a hash context. */
sbuf = (secmode
? gcry_malloc_secure (saltlen + 4 + hlen + hlen)
: gcry_malloc (saltlen + 4 + hlen + hlen));
if (!sbuf)
return gpg_err_code_from_syserror ();
tbuf = sbuf + saltlen + 4;
ubuf = tbuf + hlen;
ec = gpg_err_code (gcry_md_open (&md, hashalgo,
(GCRY_MD_FLAG_HMAC
| (secmode?GCRY_MD_FLAG_SECURE:0))));
if (ec)
{
gcry_free (sbuf);
return ec;
}
/* Step 3 and 4. */
memcpy (sbuf, salt, saltlen);
for (lidx = 1; lidx <= l; lidx++)
{
for (iter = 0; iter < iterations; iter++)
{
ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen));
if (ec)
{
gcry_md_close (md);
gcry_free (sbuf);
return ec;
}
if (!iter) /* Compute U_1: */
{
sbuf[saltlen] = (lidx >> 24);
sbuf[saltlen + 1] = (lidx >> 16);
sbuf[saltlen + 2] = (lidx >> 8);
sbuf[saltlen + 3] = lidx;
gcry_md_write (md, sbuf, saltlen + 4);
memcpy (ubuf, gcry_md_read (md, 0), hlen);
memcpy (tbuf, ubuf, hlen);
}
else /* Compute U_(2..c): */
{
gcry_md_write (md, ubuf, hlen);
memcpy (ubuf, gcry_md_read (md, 0), hlen);
for (i=0; i < hlen; i++)
tbuf[i] ^= ubuf[i];
}
}
if (lidx == l) /* Last block. */
memcpy (dk, tbuf, r);
else
{
memcpy (dk, tbuf, hlen);
dk += hlen;
}
}
gcry_md_close (md);
gcry_free (sbuf);
return 0;
}
/* Derive a key from a passphrase. KEYSIZE gives the requested size
of the keys in octets. KEYBUFFER is a caller provided buffer
filled on success with the derived key. The input passphrase is
taken from (PASSPHRASE,PASSPHRASELEN) which is an arbitrary memory
buffer. ALGO specifies the KDF algorithm to use; these are the
constants GCRY_KDF_*. SUBALGO specifies an algorithm used
internally by the KDF algorithms; this is usually a hash algorithm
but certain KDF algorithm may use it differently. {SALT,SALTLEN}
is a salt as needed by most KDF algorithms. ITERATIONS is a
positive integer parameter to most KDFs. 0 is returned on success,
or an error code on failure. */
gpg_error_t
gcry_kdf_derive (const void *passphrase, size_t passphraselen,
int algo, int subalgo,
const void *salt, size_t saltlen,
unsigned long iterations,
size_t keysize, void *keybuffer)
{
gpg_err_code_t ec;
if (!passphrase || (!passphraselen && algo != GCRY_KDF_PBKDF2))
{
ec = GPG_ERR_INV_DATA;
goto leave;
}
if (!keybuffer || !keysize)
{
ec = GPG_ERR_INV_VALUE;
goto leave;
}
switch (algo)
{
case GCRY_KDF_SIMPLE_S2K:
case GCRY_KDF_SALTED_S2K:
case GCRY_KDF_ITERSALTED_S2K:
ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo,
salt, saltlen, iterations, keysize, keybuffer);
break;
case GCRY_KDF_PBKDF1:
ec = GPG_ERR_UNSUPPORTED_ALGORITHM;
break;
case GCRY_KDF_PBKDF2:
ec = pkdf2 (passphrase, passphraselen, subalgo,
salt, saltlen, iterations, keysize, keybuffer);
break;
default:
ec = GPG_ERR_UNKNOWN_ALGORITHM;
break;
}
leave:
return gpg_error (ec);
}

View file

@ -1232,6 +1232,7 @@ md_stop_debug( gcry_md_hd_t md )
volatile u64 b = 42;
volatile u64 c;
c = a * b;
(void)c;
}
#endif
}

View file

@ -325,4 +325,3 @@ gcry_md_spec_t _gcry_digest_spec_md4 =
md4_init, md4_write, md4_final, md4_read,
sizeof (MD4_CONTEXT)
};

View file

@ -738,12 +738,12 @@ gcry_mpi_t
_gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
gcry_mpi_t g, gcry_mpi_t **ret_factors)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
gcry_mpi_t prime = NULL;
err = prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
ret_factors, GCRY_WEAK_RANDOM, 0, 0,
NULL, NULL);
if (prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
ret_factors, GCRY_WEAK_RANDOM, 0, 0,
NULL, NULL))
prime = NULL; /* (Should be NULL in the error case anyway.) */
return prime;
}
@ -1859,4 +1859,3 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
gcry_mpi_release (val_2);
return ec;
}

File diff suppressed because it is too large Load diff

View file

@ -342,4 +342,3 @@ gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = {
RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
do_setkey, do_encrypt, do_decrypt
};

View file

@ -1684,4 +1684,3 @@ static const u32 rcon[30] =
0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
};

File diff suppressed because it is too large Load diff

View file

@ -34,4 +34,3 @@ void _gcry_rmd160_init ( void *context );
void _gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte );
#endif /*G10_RMD_H*/

View file

@ -1036,8 +1036,10 @@ rsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
log_mpidump (" hash:", hash );
}
#endif /*IS_DEVELOPMENT_VERSION*/
/*rc = (*cmp)( opaquev, result );*/
rc = mpi_cmp (result, hash) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
if (cmp)
rc = (*cmp) (opaquev, result);
else
rc = mpi_cmp (result, hash) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
gcry_mpi_release (result);
return rc;
@ -1386,4 +1388,3 @@ pk_extra_spec_t _gcry_pubkey_extraspec_rsa =
rsa_generate_ext,
compute_keygrip
};

View file

@ -586,18 +586,20 @@ serpent_key_prepare (const byte *key, unsigned int key_length,
/* Copy key. */
memcpy (key_prepared, key, key_length);
key_length /= 4;
#ifdef WORDS_BIGENDIAN
for (i = 0; i < key_length / 4; i++)
for (i = 0; i < key_length; i++)
key_prepared[i] = byte_swap_32 (key_prepared[i]);
#else
i = key_length;
#endif
if (key_length < 32)
if (i < 8)
{
/* Key must be padded according to the Serpent
specification. */
key_prepared[key_length / 4] = 0x00000001;
key_prepared[i] = 0x00000001;
for (i = key_length / 4 + 1; i < 8; i++)
for (i++; i < 8; i++)
key_prepared[i] = 0;
}
}
@ -767,12 +769,12 @@ serpent_decrypt_internal (serpent_context_t *context,
serpent_block_t b, b_next;
int round = ROUNDS;
memcpy (b, input, sizeof (b));
memcpy (b_next, input, sizeof (b));
#ifdef WORDS_BIGENDIAN
b[0] = byte_swap_32 (b[0]);
b[1] = byte_swap_32 (b[1]);
b[2] = byte_swap_32 (b[2]);
b[3] = byte_swap_32 (b[3]);
b_next[0] = byte_swap_32 (b_next[0]);
b_next[1] = byte_swap_32 (b_next[1]);
b_next[2] = byte_swap_32 (b_next[2]);
b_next[3] = byte_swap_32 (b_next[3]);
#endif
ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
@ -891,9 +893,7 @@ serpent_test (void)
{
serpent_setkey_internal (&context, test_data[i].key,
test_data[i].key_length);
serpent_encrypt_internal (&context,
test_data[i].text_plain,
scratch);
serpent_encrypt_internal (&context, test_data[i].text_plain, scratch);
if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
@ -906,9 +906,7 @@ serpent_test (void)
return "Serpent-256 test encryption failed.";
}
serpent_decrypt_internal (&context,
test_data[i].text_cipher,
scratch);
serpent_decrypt_internal (&context, test_data[i].text_cipher, scratch);
if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
{

View file

@ -475,4 +475,3 @@ md_extra_spec_t _gcry_digest_extraspec_sha1 =
{
run_selftests
};

View file

@ -1,14 +1,9 @@
2011-12-01 Werner Koch <wk@g10code.com>
NB: ChangeLog files are no longer manually maintained. Starting
on December 1st, 2011 we put change information only in the GIT
commit log, and generate a top-level ChangeLog file from logs at
"make dist". See doc/HACKING for details.
2011-07-04 Werner Koch <wk@g10code.com>
* longlong.h (add_ssaaaa) [__arm__]: Do no use asm if thumb code
generation is enabled. This is bug#1202. Reported for gpg 1.4.
NB: ChangeLog files are no longer manually maintained. Starting
on December 1st, 2011 we put change information only in the GIT
commit log, and generate a top-level ChangeLog file from logs at
"make dist". See doc/HACKING for details.
2011-03-28 Werner Koch <wk@g10code.com>
@ -825,7 +820,3 @@ Mon Feb 16 13:00:27 1998 Werner Koch (wk@isil.d.shuttle.de)
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Local Variables:
buffer-read-only: t
End:

View file

@ -5,3 +5,4 @@ mpih-mul2.S
mpih-mul3.S
mpih-rshift.S
mpih-sub1.S
mpi-asm-defs.h

View file

@ -0,0 +1,4 @@
/* This file defines some basic constants for the MPI machinery. We
* need to define the types on a per-CPU basis, so it is done with
* this file here. */
#define BYTES_PER_MPI_LIMB 8

View file

@ -522,7 +522,7 @@ _gcry_mpi_ec_add_points (mpi_point_t *result,
ec_mulm (l1, l1, x1, ctx);
}
if (z1_is_one)
mpi_set (l2, x1);
mpi_set (l2, x2);
else
{
ec_powm (l2, z1, ctx->two, ctx);
@ -670,10 +670,23 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
mpi_mul (h, k, ctx->three); /* h = 3k */
loops = mpi_get_nbits (h);
mpi_set (result->x, point->x);
mpi_set (result->y, yy); mpi_free (yy); yy = NULL;
mpi_set (result->z, point->z);
if (loops < 2)
{
/* If SCALAR is zero, the above mpi_mul sets H to zero and thus
LOOPs will be zero. To avoid an underflow of I in the main
loop we set LOOP to 2 and the result to (0,0,0). */
loops = 2;
mpi_clear (result->x);
mpi_clear (result->y);
mpi_clear (result->z);
}
else
{
mpi_set (result->x, point->x);
mpi_set (result->y, yy);
mpi_set (result->z, point->z);
}
mpi_free (yy); yy = NULL;
p1.x = x1; x1 = NULL;
p1.y = y1; y1 = NULL;

View file

@ -184,28 +184,53 @@ extern UDItype __udiv_qrnnd ();
/***************************************
************** ARM ******************
***************************************/
#if defined (__arm__) && W_TYPE_SIZE == 32 && !defined (__thumb__)
#if defined (__arm__) && W_TYPE_SIZE == 32 && \
(!defined (__thumb__) || defined (__thumb2__))
/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */
#ifndef __ARM_ARCH
# ifdef __ARM_ARCH_2__
# define __ARM_ARCH 2
# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)
# define __ARM_ARCH 3
# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__)
# define __ARM_ARCH 4
# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \
|| defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
|| defined(__ARM_ARCH_5TEJ__)
# define __ARM_ARCH 5
# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|| defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
|| defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
# define __ARM_ARCH 6
# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
|| defined(__ARM_ARCH_7EM__)
# define __ARM_ARCH 7
# else
/* could not detect? */
# endif
#endif
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("adds %1, %4, %5\n" \
"adc %0, %2, %3" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"rI" ((USItype)(bh)), \
"%r" ((USItype)(al)), \
"rI" ((USItype)(bl)))
"rI" ((USItype)(bl)) __CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subs %1, %4, %5\n" \
"sbc %0, %2, %3" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(bh)), \
"r" ((USItype)(al)), \
"rI" ((USItype)(bl)))
#if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__
"rI" ((USItype)(bl)) __CLOBBER_CC)
#if (defined __ARM_ARCH && __ARM_ARCH <= 3)
#define umul_ppmm(xh, xl, a, b) \
__asm__ ("%@ Inlined umul_ppmm\n" \
__asm__ ("@ Inlined umul_ppmm\n" \
"mov %|r0, %2, lsr #16 @ AAAA\n" \
"mov %|r2, %3, lsr #16 @ BBBB\n" \
"bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \
@ -218,23 +243,28 @@ extern UDItype __udiv_qrnnd ();
"addcs %|r2, %|r2, #65536\n" \
"adds %1, %|r1, %|r0, lsl #16\n" \
"adc %0, %|r2, %|r0, lsr #16" \
: "=&r" ((USItype)(xh)), \
"=r" ((USItype)(xl)) \
: "=&r" ((xh)), \
"=r" ((xl)) \
: "r" ((USItype)(a)), \
"r" ((USItype)(b)) \
: "r0", "r1", "r2")
#else
: "r0", "r1", "r2" __CLOBBER_CC)
#else /* __ARM_ARCH >= 4 */
#define umul_ppmm(xh, xl, a, b) \
__asm__ ("%@ Inlined umul_ppmm\n" \
"umull %r1, %r0, %r2, %r3" \
: "=&r" ((USItype)(xh)), \
"=r" ((USItype)(xl)) \
__asm__ ("@ Inlined umul_ppmm\n" \
"umull %1, %0, %2, %3" \
: "=&r" ((xh)), \
"=r" ((xl)) \
: "r" ((USItype)(a)), \
"r" ((USItype)(b)) \
: "r0", "r1")
#endif
"r" ((USItype)(b)))
#endif /* __ARM_ARCH >= 4 */
#define UMUL_TIME 20
#define UDIV_TIME 100
#if (defined __ARM_ARCH && __ARM_ARCH >= 5)
#define count_leading_zeros(count, x) \
__asm__ ("clz %0, %1" \
: "=r" ((count)) \
: "r" ((USItype)(x)))
#endif /* __ARM_ARCH >= 5 */
#endif /* __arm__ */
/***************************************
@ -437,43 +467,48 @@ extern USItype __udiv_qrnnd ();
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addl %5,%1\n" \
"adcl %3,%0" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "%0" ((USItype)(ah)), \
"g" ((USItype)(bh)), \
"%1" ((USItype)(al)), \
"g" ((USItype)(bl)))
"g" ((USItype)(bl)) \
__CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subl %5,%1\n" \
"sbbl %3,%0" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "0" ((USItype)(ah)), \
"g" ((USItype)(bh)), \
"1" ((USItype)(al)), \
"g" ((USItype)(bl)))
"g" ((USItype)(bl)) \
__CLOBBER_CC)
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("mull %3" \
: "=a" ((USItype)(w0)), \
"=d" ((USItype)(w1)) \
: "=a" ((w0)), \
"=d" ((w1)) \
: "%0" ((USItype)(u)), \
"rm" ((USItype)(v)))
"rm" ((USItype)(v)) \
__CLOBBER_CC)
#define udiv_qrnnd(q, r, n1, n0, d) \
__asm__ ("divl %4" \
: "=a" ((USItype)(q)), \
"=d" ((USItype)(r)) \
: "=a" ((q)), \
"=d" ((r)) \
: "0" ((USItype)(n0)), \
"1" ((USItype)(n1)), \
"rm" ((USItype)(d)))
"rm" ((USItype)(d)) \
__CLOBBER_CC)
#define count_leading_zeros(count, x) \
do { \
USItype __cbtmp; \
__asm__ ("bsrl %1,%0" \
: "=r" (__cbtmp) : "rm" ((USItype)(x))); \
: "=r" (__cbtmp) : "rm" ((USItype)(x)) \
__CLOBBER_CC); \
(count) = __cbtmp ^ 31; \
} while (0)
#define count_trailing_zeros(count, x) \
__asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
__asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)) __CLOBBER_CC)
#ifndef UMUL_TIME
#define UMUL_TIME 40
#endif
@ -826,22 +861,22 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
do { \
if (__builtin_constant_p (bh) && (bh) == 0) \
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"%r" ((USItype)(al)), \
"rI" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"%r" ((USItype)(al)), \
"rI" ((USItype)(bl))); \
else \
__asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"r" ((USItype)(bh)), \
"%r" ((USItype)(al)), \
@ -851,36 +886,36 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
do { \
if (__builtin_constant_p (ah) && (ah) == 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) == 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else \
__asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
: "=r" ((USItype)(sh)), \
"=&r" ((USItype)(sl)) \
: "=r" ((sh)), \
"=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
@ -888,7 +923,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
} while (0)
#define count_leading_zeros(count, x) \
__asm__ ("{cntlz|cntlzw} %0,%1" \
: "=r" ((USItype)(count)) \
: "=r" ((count)) \
: "r" ((USItype)(x)))
#define COUNT_LEADING_ZEROS_0 32
#if defined (_ARCH_PPC)
@ -896,7 +931,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
do { \
USItype __m0 = (m0), __m1 = (m1); \
__asm__ ("mulhwu %0,%1,%2" \
: "=r" ((USItype) ph) \
: "=r" (ph) \
: "%r" (__m0), \
"r" (__m1)); \
(pl) = __m0 * __m1; \
@ -918,8 +953,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
do { \
USItype __m0 = (m0), __m1 = (m1); \
__asm__ ("mul %0,%2,%3" \
: "=r" ((USItype)(xh)), \
"=q" ((USItype)(xl)) \
: "=r" ((xh)), \
"=q" ((xl)) \
: "r" (__m0), \
"r" (__m1)); \
(xh) += ((((SItype) __m0 >> 31) & __m1) \

View file

@ -28,8 +28,15 @@
#ifndef G10_MPI_INLINE_H
#define G10_MPI_INLINE_H
/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the
c99 semantics. To keep the useful old semantics we use an
attribute. */
#ifndef G10_MPI_INLINE_DECL
#define G10_MPI_INLINE_DECL extern __inline__
# ifdef __GNUC_STDC_INLINE__
# define G10_MPI_INLINE_DECL extern inline __attribute__ ((__gnu_inline__))
# else
# define G10_MPI_INLINE_DECL extern __inline__
# endif
#endif
G10_MPI_INLINE_DECL mpi_limb_t

View file

@ -1,6 +1,7 @@
/* mpi-pow.c - MPI functions for exponentiation
* Copyright (C) 1994, 1996, 1998, 2000, 2002
* 2003 Free Software Foundation, Inc.
* 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@ -81,9 +82,14 @@ gcry_mpi_powm (gcry_mpi_t res,
if (!esize)
{
/* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
on if MOD equals 1. */
rp[0] = 1;
on if MOD equals 1. */
res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
if (res->nlimbs)
{
RESIZE_IF_NEEDED (res, 1);
rp = res->d;
rp[0] = 1;
}
res->sign = 0;
goto leave;
}
@ -230,7 +236,13 @@ gcry_mpi_powm (gcry_mpi_t res,
tp = rp; rp = xp; xp = tp;
rsize = xsize;
if ( (mpi_limb_signed_t)e < 0 )
/* To mitigate the Yarom/Falkner flush+reload cache
* side-channel attack on the RSA secret exponent, we do
* the multiplication regardless of the value of the
* high-bit of E. But to avoid this performance penalty
* we do it only if the exponent has been stored in secure
* memory and we can thus assume it is a secret exponent. */
if (esec || (mpi_limb_signed_t)e < 0)
{
/*mpih_mul( xp, rp, rsize, bp, bsize );*/
if( bsize < KARATSUBA_THRESHOLD )
@ -245,7 +257,9 @@ gcry_mpi_powm (gcry_mpi_t res,
_gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
xsize = msize;
}
}
if ( (mpi_limb_signed_t)e < 0 )
{
tp = rp; rp = xp; xp = tp;
rsize = xsize;
}

View file

@ -270,7 +270,7 @@ do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
/* This is sub-optimal but we need to do the shift operation because
the caller has to free the returned buffer. */
for (p=buffer; !*p && *nbytes; p++, --*nbytes)
for (p=buffer; *nbytes && !*p; p++, --*nbytes)
;
if (p != buffer)
memmove (buffer,p, *nbytes);

View file

@ -1,72 +1,13 @@
2011-12-01 Werner Koch <wk@g10code.com>
NB: ChangeLog files are no longer manually maintained. Starting
on December 1st, 2011 we put change information only in the GIT
commit log, and generate a top-level ChangeLog file from logs at
"make dist". See doc/HACKING for details.
NB: ChangeLog files are no longer manually maintained. Starting
on December 1st, 2011 we put change information only in the GIT
commit log, and generate a top-level ChangeLog file from logs at
"make dist". See doc/HACKING for details.
2011-09-16 Werner Koch <wk@g10code.com>
2011-09-08 Werner Koch <wk@g10code.com>
Change ATH code and turn the thread initialization callbacks in
the API into dummy functions.
* global.c (global_init): Call _gcry_pimegen_init.
* gcrypt.h.in (GCRY_THREAD_OPTI ON_VERSION): Bump to 1.
(GCRY_THREAD_OPTION_PTH_IMPL): Simplify.
(GCRY_THREAD_OPTION_PTHREAD_IMPL): Simplify.
* ath.c (ath_read, ath_write): Remove. They are only used in the
optional random-daemon.
(ath_select, ath_waitpid, ath_accept, ath_connect, ath_sendmsg)
(ath_recvmsg): Remove. They are not used.
* ath.h: Remove prototypes and corresponding structure fields.
2011-03-11 Werner Koch <wk@g10code.com>
* ath.c (mutex_init): Rename second arg to FORCE and invert
logic. Change all callers.
2011-09-15 Werner Koch <wk@g10code.com>
* gcrypt.h.in (enum gcry_thread_option): Remove deprecated enum.
(gcry_md_start_debug, gcry_md_stop_debug): Remove deprecated these
macros.
2011-09-15 Werner Koch <wk@g10code.com>
Removal of the gcry_ac and the module register interfaces.
* Makefile.am (include_HEADERS): Remove gcrypt-module.h.
(libgcrypt_la_SOURCES): Add gcrypt-module.h which is now internal
header.
* gcrypt-module.h (gcry_md_register, gcry_md_unregister): Remove.
(gcry_pk_register, gcry_pk_unregister): Remove.
(gcry_cipher_register, gcry_cipher_unregister): Remove.
* visibility.h: Include gcrypt-module.h.
* gcrypt.h.in: Do not include gcrypt-module.h.
* gcrypt.h.in: Remove all gcry_ac symbols.
(gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
* visibility.h: Remove all gcry_ac symbols.
(gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
(gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
(gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
* visibility.c: Remove all gcry_ac wrappers.
(gcry_pk_list, gcry_cipher_list, gcry_md_list): Remove.
(gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
(gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
* libgcrypt.vers: Remove all gcry_ac symbols.
(GCRYPT_1.2): Rename to GCRYPT_1.6.
(gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
* libgcrypt.def: Remove all gcry_ac symbols.
(gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
* global.c (global_init): Remove comment code with a call to
_gcry_ac_init.
2011-09-15 Werner Koch <wk@g10code.com>
* hmac256.c (main): Fix endless loop when using pipe input and
option --binary.
* gcrypt.h.in [GCRYPT_NO_DEPRECATED]: Exclude gcry_ac structures.
2011-06-10 Werner Koch <wk@g10code.com>
@ -2392,7 +2333,3 @@ Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Local Variables:
buffer-read-only: t
End:

View file

@ -26,7 +26,7 @@ EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
bin_SCRIPTS = libgcrypt-config
m4datadir = $(datadir)/aclocal
m4data_DATA = libgcrypt.m4
include_HEADERS = gcrypt.h
include_HEADERS = gcrypt.h gcrypt-module.h
lib_LTLIBRARIES = libgcrypt.la
bin_PROGRAMS = dumpsexp hmac256
@ -53,7 +53,7 @@ endif
libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \
cipher.h cipher-proto.h gcrypt-module.h \
cipher.h cipher-proto.h \
misc.c global.c sexp.c hwfeatures.c \
stdmem.c stdmem.h secmem.c secmem.h \
mpi.h missing-string.c module.c fips.c \

View file

@ -1,323 +1,344 @@
/* ath.c - A Thread-safeness library.
* Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/* ath.c - Thread-safeness library.
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of Libgcrypt.
Libgcrypt is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
Libgcrypt is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Libgcrypt; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <assert.h> /* Right: We need to use assert and not gcry_assert. */
#include <unistd.h>
#include <errno.h>
#if USE_POSIX_THREADS_WEAK
# include <pthread.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#else
# include <sys/time.h>
#endif
#include <sys/types.h>
#ifndef _WIN32
#include <sys/wait.h>
#endif
#include <errno.h>
#include "ath.h"
/* On an ELF system it is easy to use pthreads using weak references.
Take care not to test the address of a weak referenced function we
actually use; some GCC versions have a bug were &foo != NULL is
always evaluated to true in PIC mode. USING_PTHREAD_AS_DEFAULT is
used by ath_install to detect the default usage of pthread. */
#if USE_POSIX_THREADS_WEAK
# pragma weak pthread_cancel
# pragma weak pthread_mutex_init
# pragma weak pthread_mutex_lock
# pragma weak pthread_mutex_unlock
# pragma weak pthread_mutex_destroy
#endif
/* The interface table. */
static struct ath_ops ops;
/* For the dummy interface. The MUTEX_NOTINIT value is used to check
that a mutex has been initialized. Because its value is there is
no need to explicit initialized a mutex variable because it is
anyway static and we store a pointer to allocated memory there
after initialization. The same thing works with other thread
models. */
#define MUTEX_NOTINIT ((ath_mutex_t) 0)
#define MUTEX_UNLOCKED ((ath_mutex_t) 1)
#define MUTEX_LOCKED ((ath_mutex_t) 2)
#define MUTEX_DESTROYED ((ath_mutex_t) 3)
/* True if we should use the external callbacks. */
static int ops_set;
/* For the dummy interface. */
#define MUTEX_UNLOCKED ((ath_mutex_t) 0)
#define MUTEX_LOCKED ((ath_mutex_t) 1)
#define MUTEX_DESTROYED ((ath_mutex_t) 2)
/* Return the thread type from the option field. */
#define GET_OPTION(a) ((a) & 0xff)
/* Return the version number from the option field. */
#define GET_VERSION(a) (((a) >> 8)& 0xff)
enum ath_thread_model {
ath_model_undefined = 0,
ath_model_none, /* No thread support. */
ath_model_pthreads_weak, /* POSIX threads using weak symbols. */
ath_model_pthreads, /* POSIX threads directly linked. */
ath_model_w32 /* Microsoft Windows threads. */
};
/* The lock we take while checking for lazy lock initialization. */
static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER;
/* The thread model in use. */
static enum ath_thread_model thread_model;
/* Initialize the ath subsystem. This is called as part of the
Libgcrypt initialization. It's purpose is to initialize the
locking system. It returns 0 on sucess or an ERRNO value on error.
In the latter case it is not defined whether ERRNO was changed.
Note: This should be called as early as possible because it is not
always possible to detect the thread model to use while already
running multi threaded. */
int
ath_init (void)
{
int err = 0;
if (thread_model)
return 0; /* Already initialized - no error. */
if (0)
;
#if USE_POSIX_THREADS_WEAK
else if (pthread_cancel)
if (ops_set)
{
thread_model = ath_model_pthreads_weak;
if (ops.init)
err = (*ops.init) ();
if (err)
return err;
err = (*ops.mutex_init) (&check_init_lock);
}
#endif
else
{
/* Assume a single threaded application. */
thread_model = ath_model_none;
}
return err;
}
/* Return the used thread model as string for display purposes an if
R_MODEL is not null store its internal number at R_MODEL. */
const char *
ath_get_model (int *r_model)
{
if (r_model)
*r_model = thread_model;
switch (thread_model)
{
case ath_model_undefined: return "undefined";
case ath_model_none: return "none";
case ath_model_pthreads_weak: return "pthread(weak)";
case ath_model_pthreads: return "pthread";
case ath_model_w32: return "w32";
default: return "?";
}
}
/* This function was used in old Libgcrypt versions (via
GCRYCTL_SET_THREAD_CBS) to register the thread callback functions.
It is not anymore required. However to allow existing code to
continue to work, we keep this function and check that no user
defined callbacks are used and that the requested thread system
matches the one Libgcrypt is using. */
/* Initialize the locking library. Returns 0 if the operation was
successful, EINVAL if the operation table was invalid and EBUSY if
we already were initialized. */
gpg_err_code_t
ath_install (struct ath_ops *ath_ops)
ath_install (struct ath_ops *ath_ops, int check_only)
{
unsigned int thread_option;
/* Check if the requested thread option is compatible to the
thread option we are already committed to. */
thread_option = ath_ops? GET_OPTION (ath_ops->option) : 0;
/* Return an error if the requested thread model does not match the
configured one. */
if (0)
;
#if USE_POSIX_THREADS_WEAK
else if (thread_model == ath_model_pthreads_weak)
if (check_only)
{
if (thread_option == ATH_THREAD_OPTION_PTHREAD)
return 0; /* Okay - compatible. */
}
#endif /*USE_POSIX_THREADS_WEAK*/
else if (thread_option == ATH_THREAD_OPTION_DEFAULT)
return 0; /* No thread support requested. */
unsigned int option = 0;
return GPG_ERR_NOT_SUPPORTED;
/* Check if the requested thread option is compatible to the
thread option we are already committed to. */
if (ath_ops)
option = ath_ops->option;
if (!ops_set && GET_OPTION (option))
return GPG_ERR_NOT_SUPPORTED;
if (GET_OPTION (ops.option) == ATH_THREAD_OPTION_USER
|| GET_OPTION (option) == ATH_THREAD_OPTION_USER
|| GET_OPTION (ops.option) != GET_OPTION (option)
|| GET_VERSION (ops.option) != GET_VERSION (option))
return GPG_ERR_NOT_SUPPORTED;
return 0;
}
if (ath_ops)
{
/* It is convenient to not require DESTROY. */
if (!ath_ops->mutex_init || !ath_ops->mutex_lock
|| !ath_ops->mutex_unlock)
return GPG_ERR_INV_ARG;
ops = *ath_ops;
ops_set = 1;
}
else
ops_set = 0;
return 0;
}
static int
mutex_init (ath_mutex_t *lock, int just_check)
{
int err = 0;
if (just_check)
(*ops.mutex_lock) (&check_init_lock);
if (*lock == ATH_MUTEX_INITIALIZER || !just_check)
err = (*ops.mutex_init) (lock);
if (just_check)
(*ops.mutex_unlock) (&check_init_lock);
return err;
}
/* Initialize a new mutex. This function returns 0 on success or an
system error code (i.e. an ERRNO value). ERRNO may or may not be
changed on error. */
int
ath_mutex_init (ath_mutex_t *lock)
{
int err;
if (ops_set)
return mutex_init (lock, 0);
switch (thread_model)
{
case ath_model_none:
*lock = MUTEX_UNLOCKED;
err = 0;
break;
#if USE_POSIX_THREADS_WEAK
case ath_model_pthreads_weak:
{
pthread_mutex_t *plck;
plck = malloc (sizeof *plck);
if (!plck)
err = errno? errno : ENOMEM;
else
{
err = pthread_mutex_init (plck, NULL);
if (err)
free (plck);
else
*lock = (void*)plck;
}
}
break;
#endif /*USE_POSIX_THREADS_WEAK*/
default:
err = EINVAL;
break;
}
return err;
#ifndef NDEBUG
*lock = MUTEX_UNLOCKED;
#endif
return 0;
}
/* Destroy a mutex. This function is a NOP if LOCK is NULL. If the
mutex is still locked it can't be destroyed and the function
returns EBUSY. ERRNO may or may not be changed on error. */
int
ath_mutex_destroy (ath_mutex_t *lock)
{
int err;
if (!*lock)
return 0;
switch (thread_model)
if (ops_set)
{
case ath_model_none:
if (*lock != MUTEX_UNLOCKED)
err = EBUSY;
else
{
*lock = MUTEX_DESTROYED;
err = 0;
}
break;
if (!ops.mutex_destroy)
return 0;
#if USE_POSIX_THREADS_WEAK
case ath_model_pthreads_weak:
{
pthread_mutex_t *plck = (pthread_mutex_t*)lock;
err = pthread_mutex_destroy (plck);
if (!err)
{
free (plck);
lock = NULL;
}
}
break;
#endif /*USE_POSIX_THREADS_WEAK*/
default:
err = EINVAL;
break;
(*ops.mutex_lock) (&check_init_lock);
if (*lock == ATH_MUTEX_INITIALIZER)
{
(*ops.mutex_unlock) (&check_init_lock);
return 0;
}
(*ops.mutex_unlock) (&check_init_lock);
return (*ops.mutex_destroy) (lock);
}
return err;
#ifndef NDEBUG
assert (*lock == MUTEX_UNLOCKED);
*lock = MUTEX_DESTROYED;
#endif
return 0;
}
/* Lock the mutex LOCK. On success the function returns 0; on error
an error code. ERRNO may or may not be changed on error. */
int
ath_mutex_lock (ath_mutex_t *lock)
{
int err;
switch (thread_model)
if (ops_set)
{
case ath_model_none:
if (*lock == MUTEX_NOTINIT)
err = EINVAL;
else if (*lock == MUTEX_UNLOCKED)
{
*lock = MUTEX_LOCKED;
err = 0;
}
else
err = EDEADLK;
break;
#if USE_POSIX_THREADS_WEAK
case ath_model_pthreads_weak:
err = pthread_mutex_lock ((pthread_mutex_t*)lock);
break;
#endif /*USE_POSIX_THREADS_WEAK*/
default:
err = EINVAL;
break;
int ret = mutex_init (lock, 1);
if (ret)
return ret;
return (*ops.mutex_lock) (lock);
}
return err;
#ifndef NDEBUG
assert (*lock == MUTEX_UNLOCKED);
*lock = MUTEX_LOCKED;
#endif
return 0;
}
/* Unlock the mutex LOCK. On success the function returns 0; on error
an error code. ERRNO may or may not be changed on error. */
int
ath_mutex_unlock (ath_mutex_t *lock)
{
int err;
switch (thread_model)
if (ops_set)
{
case ath_model_none:
if (*lock == MUTEX_NOTINIT)
err = EINVAL;
else if (*lock == MUTEX_LOCKED)
{
*lock = MUTEX_UNLOCKED;
err = 0;
}
else
err = EPERM;
break;
#if USE_POSIX_THREADS_WEAK
case ath_model_pthreads_weak:
err = pthread_mutex_unlock ((pthread_mutex_t*)lock);
break;
#endif /*USE_POSIX_THREADS_WEAK*/
default:
err = EINVAL;
break;
int ret = mutex_init (lock, 1);
if (ret)
return ret;
return (*ops.mutex_unlock) (lock);
}
return err;
#ifndef NDEBUG
assert (*lock == MUTEX_LOCKED);
*lock = MUTEX_UNLOCKED;
#endif
return 0;
}
ssize_t
ath_read (int fd, void *buf, size_t nbytes)
{
if (ops_set && ops.read)
return (*ops.read) (fd, buf, nbytes);
else
return read (fd, buf, nbytes);
}
ssize_t
ath_write (int fd, const void *buf, size_t nbytes)
{
if (ops_set && ops.write)
return (*ops.write) (fd, buf, nbytes);
else
return write (fd, buf, nbytes);
}
ssize_t
#ifdef _WIN32
ath_select (int nfd, void *rset, void *wset, void *eset,
struct timeval *timeout)
#else
ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout)
#endif
{
if (ops_set && ops.select)
return (*ops.select) (nfd, rset, wset, eset, timeout);
else
#ifdef _WIN32
return -1;
#else
return select (nfd, rset, wset, eset, timeout);
#endif
}
ssize_t
ath_waitpid (pid_t pid, int *status, int options)
{
if (ops_set && ops.waitpid)
return (*ops.waitpid) (pid, status, options);
else
#ifdef _WIN32
return -1;
#else
return waitpid (pid, status, options);
#endif
}
int
#ifdef _WIN32
ath_accept (int s, void *addr, int *length_ptr)
#else
ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
#endif
{
if (ops_set && ops.accept)
return (*ops.accept) (s, addr, length_ptr);
else
#ifdef _WIN32
return -1;
#else
return accept (s, addr, length_ptr);
#endif
}
int
#ifdef _WIN32
ath_connect (int s, void *addr, int length)
#else
ath_connect (int s, struct sockaddr *addr, socklen_t length)
#endif
{
if (ops_set && ops.connect)
return (*ops.connect) (s, addr, length);
else
#ifdef _WIN32
return -1;
#else
return connect (s, addr, length);
#endif
}
int
#ifdef _WIN32
ath_sendmsg (int s, const void *msg, int flags)
#else
ath_sendmsg (int s, const struct msghdr *msg, int flags)
#endif
{
if (ops_set && ops.sendmsg)
return (*ops.sendmsg) (s, msg, flags);
else
#ifdef _WIN32
return -1;
#else
return sendmsg (s, msg, flags);
#endif
}
int
#ifdef _WIN32
ath_recvmsg (int s, void *msg, int flags)
#else
ath_recvmsg (int s, struct msghdr *msg, int flags)
#endif
{
if (ops_set && ops.recvmsg)
return (*ops.recvmsg) (s, msg, flags);
else
#ifdef _WIN32
return -1;
#else
return recvmsg (s, msg, flags);
#endif
}

View file

@ -1,21 +1,22 @@
/* ath.h - Thread-safeness library.
* Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of Libgcrypt.
Libgcrypt is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
Libgcrypt is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Libgcrypt; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifndef ATH_H
#define ATH_H
@ -50,11 +51,18 @@
#define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x)
#define ath_install _ATH_PREFIX(ath_install)
#define ath_init _ATH_PREFIX(ath_init)
#define ath_get_model _ATH_PREFIX(ath_get_model)
#define ath_mutex_init _ATH_PREFIX(ath_mutex_init)
#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy)
#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock)
#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock)
#define ath_read _ATH_PREFIX(ath_read)
#define ath_write _ATH_PREFIX(ath_write)
#define ath_select _ATH_PREFIX(ath_select)
#define ath_waitpid _ATH_PREFIX(ath_waitpid)
#define ath_connect _ATH_PREFIX(ath_connect)
#define ath_accept _ATH_PREFIX(ath_accept)
#define ath_sendmsg _ATH_PREFIX(ath_sendmsg)
#define ath_recvmsg _ATH_PREFIX(ath_recvmsg)
#endif
@ -75,18 +83,65 @@ struct ath_ops
*/
unsigned int option;
int (*init) (void);
int (*mutex_init) (void **priv);
int (*mutex_destroy) (void *priv);
int (*mutex_lock) (void *priv);
int (*mutex_unlock) (void *priv);
ssize_t (*read) (int fd, void *buf, size_t nbytes);
ssize_t (*write) (int fd, const void *buf, size_t nbytes);
#ifdef _WIN32
ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
struct timeval *timeout);
ssize_t (*waitpid) (pid_t pid, int *status, int options);
int (*accept) (int s, void *addr, int *length_ptr);
int (*connect) (int s, void *addr, int length);
int (*sendmsg) (int s, const void *msg, int flags);
int (*recvmsg) (int s, void *msg, int flags);
#else
ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout);
ssize_t (*waitpid) (pid_t pid, int *status, int options);
int (*accept) (int s, struct sockaddr *addr, socklen_t *length_ptr);
int (*connect) (int s, struct sockaddr *addr, socklen_t length);
int (*sendmsg) (int s, const struct msghdr *msg, int flags);
int (*recvmsg) (int s, struct msghdr *msg, int flags);
#endif
};
gpg_err_code_t ath_install (struct ath_ops *ath_ops);
gpg_err_code_t ath_install (struct ath_ops *ath_ops, int check_only);
int ath_init (void);
const char *ath_get_model (int *r_model);
/* Functions for mutual exclusion. */
typedef void *ath_mutex_t;
#define ATH_MUTEX_INITIALIZER 0
int ath_mutex_init (ath_mutex_t *mutex);
int ath_mutex_destroy (ath_mutex_t *mutex);
int ath_mutex_lock (ath_mutex_t *mutex);
int ath_mutex_unlock (ath_mutex_t *mutex);
/* Replacement for the POSIX functions, which can be used to allow
other (user-level) threads to run. */
ssize_t ath_read (int fd, void *buf, size_t nbytes);
ssize_t ath_write (int fd, const void *buf, size_t nbytes);
#ifdef _WIN32
ssize_t ath_select (int nfd, void *rset, void *wset, void *eset,
struct timeval *timeout);
ssize_t ath_waitpid (pid_t pid, int *status, int options);
int ath_accept (int s, void *addr, int *length_ptr);
int ath_connect (int s, void *addr, int length);
int ath_sendmsg (int s, const void *msg, int flags);
int ath_recvmsg (int s, void *msg, int flags);
#else
ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout);
ssize_t ath_waitpid (pid_t pid, int *status, int options);
int ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
int ath_connect (int s, struct sockaddr *addr, socklen_t length);
int ath_sendmsg (int s, const struct msghdr *msg, int flags);
int ath_recvmsg (int s, struct msghdr *msg, int flags);
#endif
#endif /* ATH_H */

View file

@ -135,6 +135,7 @@ extern gcry_cipher_spec_t _gcry_cipher_spec_seed;
extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128;
extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192;
extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256;
extern gcry_cipher_spec_t _gcry_cipher_spec_idea;
extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes;
extern cipher_extra_spec_t _gcry_cipher_extraspec_aes;

View file

@ -69,7 +69,7 @@ static int enforced_fips_mode;
static int inactive_fips_mode;
/* This is the lock we use to protect the FSM. */
static ath_mutex_t fsm_lock;
static ath_mutex_t fsm_lock = ATH_MUTEX_INITIALIZER;
/* The current state of the FSM. The whole state machinery is only
used while in fips mode. Change this only while holding fsm_lock. */
@ -274,9 +274,17 @@ _gcry_fips_mode (void)
int
_gcry_enforced_fips_mode (void)
{
if (!_gcry_fips_mode ())
return 0;
return enforced_fips_mode;
}
/* Set a flag telling whether we are in the enforced fips mode. */
void
_gcry_set_enforced_fips_mode (void)
{
enforced_fips_mode = 1;
}
/* If we do not want to enforce the fips mode, we can set a flag so
that the application may check whether it is still in fips mode.

View file

@ -69,8 +69,6 @@
/* Gettext macros. */
#define _(a) _gcry_gettext(a)
/* Some handy macros */
#ifndef STR
#define STR(v) #v
@ -116,9 +114,20 @@ void _gcry_log_printhex (const char *text, const void *buffer, size_t length);
void _gcry_set_log_verbosity( int level );
int _gcry_log_verbosity( int level );
#ifdef JNLIB_GCC_M_FUNCTION
#define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ )
#define gcry_assert(expr) ((expr)? (void)0 \
: _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __FUNCTION__))
#elif __STDC_VERSION__ >= 199901L
#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ )
#define gcry_assert(expr) ((expr)? (void)0 \
: _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__))
#else
#define BUG() _gcry_bug( __FILE__ , __LINE__ )
#define gcry_assert(expr) ((expr)? (void)0 \
: _gcry_assert_failed (STR(expr), __FILE__, __LINE__))
#endif
#define log_bug _gcry_log_bug
#define log_fatal _gcry_log_fatal
@ -155,7 +164,6 @@ const char *_gcry_mpi_get_hw_config (void);
#endif
/*-- primegen.c --*/
gcry_err_code_t _gcry_primegen_init (void);
gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits,
gcry_random_level_t random_level,
int (*extra_check)(void*, gcry_mpi_t),
@ -238,66 +246,6 @@ void _gcry_burn_stack (int bytes);
|| (*(a) >= 'A' && *(a) <= 'F') \
|| (*(a) >= 'a' && *(a) <= 'f'))
/* Management for ciphers/digests/pubkey-ciphers. */
/* Structure for each registered `module'. */
struct gcry_module
{
struct gcry_module *next; /* List pointers. */
struct gcry_module **prevp;
void *spec; /* Pointer to the subsystem-specific
specification structure. */
void *extraspec; /* Pointer to the subsystem-specific
extra specification structure. */
int flags; /* Associated flags. */
int counter; /* Use counter. */
unsigned int mod_id; /* ID of this module. */
};
typedef struct gcry_module gcry_module_t;
/* Flags for the `flags' member of gcry_module_t. */
#define FLAG_MODULE_DISABLED (1 << 0)
gcry_err_code_t _gcry_module_add (gcry_module_t *entries,
unsigned int id,
void *spec,
void *extraspec,
gcry_module_t *module);
typedef int (*gcry_module_lookup_t) (void *spec, void *data);
/* Lookup a module specification by it's ID. After a successful
lookup, the module has it's resource counter incremented. */
gcry_module_t _gcry_module_lookup_id (gcry_module_t entries,
unsigned int id);
/* Internal function. Lookup a module specification. */
gcry_module_t _gcry_module_lookup (gcry_module_t entries, void *data,
gcry_module_lookup_t func);
/* Release a module. In case the use-counter reaches zero, destroy
the module. */
void _gcry_module_release (gcry_module_t entry);
/* Add a reference to a module. */
void _gcry_module_use (gcry_module_t module);
/* Return a list of module IDs. */
gcry_err_code_t _gcry_module_list (gcry_module_t modules,
int *list, int *list_length);
gcry_err_code_t _gcry_cipher_init (void);
gcry_err_code_t _gcry_md_init (void);
gcry_err_code_t _gcry_pk_init (void);
gcry_err_code_t _gcry_pk_module_lookup (int id, gcry_module_t *module);
void _gcry_pk_module_release (gcry_module_t module);
gcry_err_code_t _gcry_pk_get_elements (int algo, char **enc, char **sig);
/* Memory management. */
#define GCRY_ALLOC_FLAG_SECURE (1 << 0)
/*-- sexp.c --*/
gcry_error_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
@ -309,8 +257,13 @@ char *_gcry_sexp_nth_string (const gcry_sexp_t list, int number);
void _gcry_initialize_fips_mode (int force);
int _gcry_fips_mode (void);
#define fips_mode() _gcry_fips_mode ()
int _gcry_enforced_fips_mode (void);
void _gcry_set_enforced_fips_mode (void);
void _gcry_inactivate_fips_mode (const char *text);
int _gcry_is_fips_mode_inactive (void);

View file

@ -19,13 +19,11 @@
/*
This file contains the necessary declarations/definitions for
working with Libgcrypt modules. Since 1.6 this is an internal
interface and will eventually be merged into another header or
entirely removed.
working with Libgcrypt modules.
*/
#ifndef GCRYPT_MODULE_H
#define GCRYPT_MODULE_H
#ifndef _GCRYPT_MODULE_H
#define _GCRYPT_MODULE_H
#ifdef __cplusplus
extern "C" {
@ -95,6 +93,19 @@ typedef struct gcry_cipher_spec
gcry_cipher_stdecrypt_t stdecrypt;
} gcry_cipher_spec_t;
/* Register a new cipher module whose specification can be found in
CIPHER. On success, a new algorithm ID is stored in ALGORITHM_ID
and a pointer representing this module is stored in MODULE. */
gcry_error_t gcry_cipher_register (gcry_cipher_spec_t *cipher,
int *algorithm_id,
gcry_module_t *module)
/* */ _GCRY_ATTR_INTERNAL;
/* Unregister the cipher identified by MODULE, which must have been
registered with gcry_cipher_register. */
void gcry_cipher_unregister (gcry_module_t module)
/* */ _GCRY_ATTR_INTERNAL;
/* ********************** */
@ -160,6 +171,18 @@ typedef struct gcry_pk_spec
gcry_pk_get_nbits_t get_nbits;
} gcry_pk_spec_t;
/* Register a new pubkey module whose specification can be found in
PUBKEY. On success, a new algorithm ID is stored in ALGORITHM_ID
and a pointer representhing this module is stored in MODULE. */
gcry_error_t gcry_pk_register (gcry_pk_spec_t *pubkey,
unsigned int *algorithm_id,
gcry_module_t *module)
/* */ _GCRY_ATTR_INTERNAL;
/* Unregister the pubkey identified by ID, which must have been
registered with gcry_pk_register. */
void gcry_pk_unregister (gcry_module_t module)
/* */ _GCRY_ATTR_INTERNAL;
/* ********************** */
@ -195,10 +218,23 @@ typedef struct gcry_md_spec
size_t contextsize; /* allocate this amount of context */
} gcry_md_spec_t;
/* Register a new digest module whose specification can be found in
DIGEST. On success, a new algorithm ID is stored in ALGORITHM_ID
and a pointer representhing this module is stored in MODULE. */
gcry_error_t gcry_md_register (gcry_md_spec_t *digest,
unsigned int *algorithm_id,
gcry_module_t *module)
/* */ _GCRY_ATTR_INTERNAL;
/* Unregister the digest identified by ID, which must have been
registered with gcry_digest_register. */
void gcry_md_unregister (gcry_module_t module)
/* */ _GCRY_ATTR_INTERNAL;
#if 0 /* keep Emacsens's auto-indent happy */
{
#endif
#ifdef __cplusplus
}
#endif
#endif /*GCRYPT_MODULE_H*/
#endif

View file

@ -1,6 +1,8 @@
/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*-
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
2007, 2008, 2009, 2010, 2011,
2012 Free Software Foundation, Inc.
Copyright (C) 2012, 2013 g10 Code GmbH
This file is part of Libgcrypt.
@ -63,6 +65,11 @@ extern "C" {
matches the installed library. */
#define GCRYPT_VERSION "@VERSION@"
/* The version number of this header. It may be used to handle minor
API incompatibilities. */
#define GCRYPT_VERSION_NUMBER @VERSION_NUMBER@
/* Internal: We can't use the convenience macros for the multi
precision integer functions when building this library. */
#ifdef _GCRYPT_IN_LIBGCRYPT
@ -173,41 +180,6 @@ gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
/* Return an error value with the system error ERR. */
gcry_err_code_t gcry_error_from_errno (int err);
/* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore
used. However we keep it to allow for some source code
compatibility if used in the standard way. */
/* Constants defining the thread model to use. Used with the OPTION
field of the struct gcry_thread_cbs. */
#define GCRY_THREAD_OPTION_DEFAULT 0
#define GCRY_THREAD_OPTION_USER 1
#define GCRY_THREAD_OPTION_PTH 2
#define GCRY_THREAD_OPTION_PTHREAD 3
/* The version number encoded in the OPTION field of the struct
gcry_thread_cbs. */
#define GCRY_THREAD_OPTION_VERSION 1
/* Wrapper for struct ath_ops. */
struct gcry_thread_cbs
{
/* The OPTION field encodes the thread model and the version number
of this structure.
Bits 7 - 0 are used for the thread model
Bits 15 - 8 are used for the version number. */
unsigned int option;
} _GCRY_ATTR_INTERNAL;
#define GCRY_THREAD_OPTION_PTH_IMPL \
static struct gcry_thread_cbs gcry_threads_pth = { \
(GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8))}
#define GCRY_THREAD_OPTION_PTHREAD_IMPL \
static struct gcry_thread_cbs gcry_threads_pthread = { \
(GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))}
/* The data object used to hold a multi precision integer. */
struct gcry_mpi;
@ -285,7 +257,8 @@ enum gcry_ctl_cmds
GCRYCTL_FORCE_FIPS_MODE = 56,
GCRYCTL_SELFTEST = 57,
/* Note: 58 .. 62 are used internally. */
GCRYCTL_DISABLE_HWF = 63
GCRYCTL_DISABLE_HWF = 63,
GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64
};
/* Perform various operations defined by CMD. */
@ -821,6 +794,14 @@ size_t gcry_cipher_get_algo_blklen (int algo);
#define gcry_cipher_test_algo(a) \
gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
/* Get a list consisting of the IDs of the loaded cipher modules. If
LIST is zero, write the number of loaded cipher modules to
LIST_LENGTH and return. If LIST is non-zero, the first
*LIST_LENGTH algorithm IDs are stored in LIST, which must be of
according size. In case there are less cipher modules than
*LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
gcry_error_t gcry_cipher_list (int *list, int *list_length);
/************************************
* *
@ -911,6 +892,13 @@ gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
#define gcry_pk_test_algo(a) \
gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
/* Get a list consisting of the IDs of the loaded pubkey modules. If
LIST is zero, write the number of loaded pubkey modules to
LIST_LENGTH and return. If LIST is non-zero, the first
*LIST_LENGTH algorithm IDs are stored in LIST, which must be of
according size. In case there are less pubkey modules than
*LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
gcry_error_t gcry_pk_list (int *list, int *list_length);
@ -1081,6 +1069,438 @@ void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
#define gcry_md_get_asnoid(a,b,n) \
gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
/* Enable debugging for digest object A; i.e. create files named
dbgmd-<n>.<string> while hashing. B is a string used as the suffix
for the filename. This macro is deprecated, use gcry_md_debug. */
#ifndef GCRYPT_NO_DEPRECATED
#define gcry_md_start_debug(a,b) \
gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 )
/* Disable the debugging of A. This macro is deprecated, use
gcry_md_debug. */
#define gcry_md_stop_debug(a,b) \
gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 )
#endif
/* Get a list consisting of the IDs of the loaded message digest
modules. If LIST is zero, write the number of loaded message
digest modules to LIST_LENGTH and return. If LIST is non-zero, the
first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
of according size. In case there are less message digest modules
than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
number. */
gcry_error_t gcry_md_list (int *list, int *list_length);
#if !defined(GCRYPT_NO_DEPRECATED) || defined(_GCRYPT_IN_LIBGCRYPT)
/* Alternative interface for asymmetric cryptography. This interface
is deprecated. */
/* The algorithm IDs. */
typedef enum gcry_ac_id
{
GCRY_AC_RSA = 1,
GCRY_AC_DSA = 17,
GCRY_AC_ELG = 20,
GCRY_AC_ELG_E = 16
}
gcry_ac_id_t _GCRY_ATTR_INTERNAL;
/* Key types. */
typedef enum gcry_ac_key_type
{
GCRY_AC_KEY_SECRET,
GCRY_AC_KEY_PUBLIC
}
gcry_ac_key_type_t _GCRY_ATTR_INTERNAL;
/* Encoding methods. */
typedef enum gcry_ac_em
{
GCRY_AC_EME_PKCS_V1_5,
GCRY_AC_EMSA_PKCS_V1_5
}
gcry_ac_em_t _GCRY_ATTR_INTERNAL;
/* Encryption and Signature schemes. */
typedef enum gcry_ac_scheme
{
GCRY_AC_ES_PKCS_V1_5,
GCRY_AC_SSA_PKCS_V1_5
}
gcry_ac_scheme_t _GCRY_ATTR_INTERNAL;
/* AC data. */
#define GCRY_AC_FLAG_DEALLOC (1 << 0)
#define GCRY_AC_FLAG_COPY (1 << 1)
#define GCRY_AC_FLAG_NO_BLINDING (1 << 2)
/* This type represents a `data set'. */
typedef struct gcry_ac_data *gcry_ac_data_t _GCRY_ATTR_INTERNAL;
/* This type represents a single `key', either a secret one or a
public one. */
typedef struct gcry_ac_key *gcry_ac_key_t _GCRY_ATTR_INTERNAL;
/* This type represents a `key pair' containing a secret and a public
key. */
typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t _GCRY_ATTR_INTERNAL;
/* This type represents a `handle' that is needed by functions
performing cryptographic operations. */
typedef struct gcry_ac_handle *gcry_ac_handle_t _GCRY_ATTR_INTERNAL;
typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque,
unsigned char *buffer,
size_t *buffer_n)
/* */ _GCRY_ATTR_INTERNAL;
typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque,
unsigned char *buffer,
size_t buffer_n)
/* */ _GCRY_ATTR_INTERNAL;
typedef enum
{
GCRY_AC_IO_READABLE,
GCRY_AC_IO_WRITABLE
}
gcry_ac_io_mode_t _GCRY_ATTR_INTERNAL;
typedef enum
{
GCRY_AC_IO_STRING,
GCRY_AC_IO_CALLBACK
}
gcry_ac_io_type_t _GCRY_ATTR_INTERNAL;
typedef struct gcry_ac_io
{
/* This is an INTERNAL structure, do NOT use manually. */
gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL;
gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL;
union
{
union
{
struct
{
gcry_ac_data_read_cb_t cb;
void *opaque;
} callback;
struct
{
unsigned char *data;
size_t data_n;
} string;
void *opaque;
} readable;
union
{
struct
{
gcry_ac_data_write_cb_t cb;
void *opaque;
} callback;
struct
{
unsigned char **data;
size_t *data_n;
} string;
void *opaque;
} writable;
} io _GCRY_ATTR_INTERNAL;
}
gcry_ac_io_t _GCRY_ATTR_INTERNAL;
/* The caller of gcry_ac_key_pair_generate can provide one of these
structures in order to influence the key generation process in an
algorithm-specific way. */
typedef struct gcry_ac_key_spec_rsa
{
gcry_mpi_t e; /* E to use. */
} gcry_ac_key_spec_rsa_t _GCRY_ATTR_INTERNAL;
/* Structure used for passing data to the implementation of the
`EME-PKCS-V1_5' encoding method. */
typedef struct gcry_ac_eme_pkcs_v1_5
{
size_t key_size;
} gcry_ac_eme_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
typedef enum gcry_md_algos gcry_md_algo_t _GCRY_ATTR_INTERNAL;
/* Structure used for passing data to the implementation of the
`EMSA-PKCS-V1_5' encoding method. */
typedef struct gcry_ac_emsa_pkcs_v1_5
{
gcry_md_algo_t md;
size_t em_n;
} gcry_ac_emsa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
/* Structure used for passing data to the implementation of the
`SSA-PKCS-V1_5' signature scheme. */
typedef struct gcry_ac_ssa_pkcs_v1_5
{
gcry_md_algo_t md;
} gcry_ac_ssa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
#endif /* !GCRYPT_NO_DEPRECATED || !_GCRYPT_IN_LIBGCRYPT */
#ifndef GCRYPT_NO_DEPRECATED
/* Returns a new, empty data set in DATA. */
gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data)
/* */ _GCRY_ATTR_INTERNAL;
/* Destroy the data set DATA. */
void gcry_ac_data_destroy (gcry_ac_data_t data)
/* */ _GCRY_ATTR_INTERNAL;
/* Create a copy of the data set DATA and store it in DATA_CP. */
gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
gcry_ac_data_t data)
/* */ _GCRY_ATTR_INTERNAL;
/* Return the number of named MPI values inside of the data set
DATA. */
unsigned int gcry_ac_data_length (gcry_ac_data_t data)
/* */ _GCRY_ATTR_INTERNAL;
/* Destroy any values contained in the data set DATA. */
void gcry_ac_data_clear (gcry_ac_data_t data)
/* */ _GCRY_ATTR_INTERNAL;
/* Add the value MPI to DATA with the label NAME. If FLAGS contains
GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME
and MPI. If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or
GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will
be deallocated when they are to be removed from the data set. */
gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
const char *name, gcry_mpi_t mpi)
/* */ _GCRY_ATTR_INTERNAL;
/* Store the value labelled with NAME found in DATA in MPI. If FLAGS
contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained
in the data set. MPI may be NULL. */
gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
const char *name, gcry_mpi_t *mpi)
/* */ _GCRY_ATTR_INTERNAL;
/* Stores in NAME and MPI the named MPI value contained in the data
set DATA with the index IDX. If FLAGS contains GCRY_AC_FLAG_COPY,
store copies of the values contained in the data set. NAME or MPI
may be NULL. */
gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
unsigned int idx,
const char **name, gcry_mpi_t *mpi)
/* */ _GCRY_ATTR_INTERNAL;
/* Convert the data set DATA into a new S-Expression, which is to be
stored in SEXP, according to the identifiers contained in
IDENTIFIERS. */
gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
const char **identifiers)
/* */ _GCRY_ATTR_INTERNAL;
/* Create a new data set, which is to be stored in DATA_SET, from the
S-Expression SEXP, according to the identifiers contained in
IDENTIFIERS. */
gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
const char **identifiers)
/* */ _GCRY_ATTR_INTERNAL;
/* Initialize AC_IO according to MODE, TYPE and the variable list of
arguments. The list of variable arguments to specify depends on
the given TYPE. */
void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
gcry_ac_io_type_t type, ...)
/* */ _GCRY_ATTR_INTERNAL;
/* Initialize AC_IO according to MODE, TYPE and the variable list of
arguments AP. The list of variable arguments to specify depends on
the given TYPE. */
void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
gcry_ac_io_type_t type, va_list ap)
/* */ _GCRY_ATTR_INTERNAL;
/* Create a new ac handle. */
gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
gcry_ac_id_t algorithm, unsigned int flags)
/* */ _GCRY_ATTR_INTERNAL;
/* Destroy an ac handle. */
void gcry_ac_close (gcry_ac_handle_t handle)
/* */ _GCRY_ATTR_INTERNAL;
/* Initialize a key from a given data set. */
gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
gcry_ac_key_type_t type, gcry_ac_data_t data)
/* */ _GCRY_ATTR_INTERNAL;
/* Generates a new key pair via the handle HANDLE of NBITS bits and
stores it in KEY_PAIR. In case non-standard settings are wanted, a
pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
matching the selected algorithm, can be given as KEY_SPEC.
MISC_DATA is not used yet. */
gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
unsigned int nbits, void *spec,
gcry_ac_key_pair_t *key_pair,
gcry_mpi_t **misc_data)
/* */ _GCRY_ATTR_INTERNAL;
/* Returns the key of type WHICH out of the key pair KEY_PAIR. */
gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
gcry_ac_key_type_t which)
/* */ _GCRY_ATTR_INTERNAL;
/* Returns the data set contained in the key KEY. */
gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key)
/* */ _GCRY_ATTR_INTERNAL;
/* Verifies that the key KEY is sane via HANDLE. */
gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
/* */ _GCRY_ATTR_INTERNAL;
/* Stores the number of bits of the key KEY in NBITS via HANDLE. */
gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
gcry_ac_key_t key, unsigned int *nbits)
/* */ _GCRY_ATTR_INTERNAL;
/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
HANDLE. */
gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
unsigned char *key_grip)
/* */ _GCRY_ATTR_INTERNAL;
/* Destroy a key. */
void gcry_ac_key_destroy (gcry_ac_key_t key)
/* */ _GCRY_ATTR_INTERNAL;
/* Destroy a key pair. */
void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
/* */ _GCRY_ATTR_INTERNAL;
/* Encodes a message according to the encoding method METHOD. OPTIONS
must be a pointer to a method-specific structure
(gcry_ac_em*_t). */
gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
unsigned int flags, void *options,
gcry_ac_io_t *io_read,
gcry_ac_io_t *io_write)
/* */ _GCRY_ATTR_INTERNAL;
/* Decodes a message according to the encoding method METHOD. OPTIONS
must be a pointer to a method-specific structure
(gcry_ac_em*_t). */
gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
unsigned int flags, void *options,
gcry_ac_io_t *io_read,
gcry_ac_io_t *io_write)
/* */ _GCRY_ATTR_INTERNAL;
/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under
the control of the flags FLAGS and store the resulting data set
into DATA_ENCRYPTED. */
gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
unsigned int flags,
gcry_ac_key_t key,
gcry_mpi_t data_plain,
gcry_ac_data_t *data_encrypted)
/* */ _GCRY_ATTR_INTERNAL;
/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED
with the key KEY under the control of the flags FLAGS and store the
resulting plain text MPI value in DATA_PLAIN. */
gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
unsigned int flags,
gcry_ac_key_t key,
gcry_mpi_t *data_plain,
gcry_ac_data_t data_encrypted)
/* */ _GCRY_ATTR_INTERNAL;
/* Sign the data contained in DATA with the key KEY and store the
resulting signature in the data set DATA_SIGNATURE. */
gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
gcry_ac_key_t key,
gcry_mpi_t data,
gcry_ac_data_t *data_signature)
/* */ _GCRY_ATTR_INTERNAL;
/* Verify that the signature contained in the data set DATA_SIGNATURE
is indeed the result of signing the data contained in DATA with the
secret key belonging to the public key KEY. */
gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
gcry_ac_key_t key,
gcry_mpi_t data,
gcry_ac_data_t data_signature)
/* */ _GCRY_ATTR_INTERNAL;
/* Encrypts the plain text readable from IO_MESSAGE through HANDLE
with the public key KEY according to SCHEME, FLAGS and OPTS. If
OPTS is not NULL, it has to be a pointer to a structure specific to
the chosen scheme (gcry_ac_es_*_t). The encrypted message is
written to IO_CIPHER. */
gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_message,
gcry_ac_io_t *io_cipher)
/* */ _GCRY_ATTR_INTERNAL;
/* Decrypts the cipher text readable from IO_CIPHER through HANDLE
with the secret key KEY according to SCHEME, @var{flags} and OPTS.
If OPTS is not NULL, it has to be a pointer to a structure specific
to the chosen scheme (gcry_ac_es_*_t). The decrypted message is
written to IO_MESSAGE. */
gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_cipher,
gcry_ac_io_t *io_message)
/* */ _GCRY_ATTR_INTERNAL;
/* Signs the message readable from IO_MESSAGE through HANDLE with the
secret key KEY according to SCHEME, FLAGS and OPTS. If OPTS is not
NULL, it has to be a pointer to a structure specific to the chosen
scheme (gcry_ac_ssa_*_t). The signature is written to
IO_SIGNATURE. */
gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_message,
gcry_ac_io_t *io_signature)
/* */ _GCRY_ATTR_INTERNAL;
/* Verifies through HANDLE that the signature readable from
IO_SIGNATURE is indeed the result of signing the message readable
from IO_MESSAGE with the secret key belonging to the public key KEY
according to SCHEME and OPTS. If OPTS is not NULL, it has to be an
anonymous structure (gcry_ac_ssa_*_t) specific to the chosen
scheme. */
gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_message,
gcry_ac_io_t *io_signature)
/* */ _GCRY_ATTR_INTERNAL;
/* Store the textual representation of the algorithm whose id is given
in ALGORITHM in NAME. This function is deprecated; use
gcry_pk_algo_name. */
gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm,
const char **name)
/* */ _GCRY_GCC_ATTR_DEPRECATED;
/* Store the numeric ID of the algorithm whose textual representation
is contained in NAME in ALGORITHM. This function is deprecated;
use gcry_pk_map_name. */
gcry_error_t gcry_ac_name_to_id (const char *name,
gcry_ac_id_t *algorithm)
/* */ _GCRY_GCC_ATTR_DEPRECATED;
#endif /*GCRYPT_NO_DEPRECATED*/
/******************************
@ -1323,6 +1743,9 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
/* Include support for Libgcrypt modules. */
#include <gcrypt-module.h>
#if 0 /* (Keep Emacsens' auto-indent happy.) */
{
#endif

View file

@ -104,21 +104,16 @@ global_init (void)
/* Initialize our portable thread/mutex wrapper. */
err = ath_init ();
if (err)
{
err = gpg_error_from_errno (err);
goto fail;
}
goto fail;
/* See whether the system is in FIPS mode. This needs to come as
early as possible but after ATH has been initialized. */
early as possible put after the ATH has been initialized. */
_gcry_initialize_fips_mode (force_fips_mode);
/* Before we do any other initialization we need to test available
hardware features. */
_gcry_detect_hw_features (disabled_hw_features);
/* Initialize the modules - this is mainly allocating some memory and
creating mutexes. */
err = _gcry_cipher_init ();
if (err)
goto fail;
@ -128,9 +123,15 @@ global_init (void)
err = _gcry_pk_init ();
if (err)
goto fail;
err = _gcry_primegen_init ();
if (err)
goto fail;
#if 0
/* Hmmm, as of now ac_init does nothing. */
if ( !fips_mode () )
{
err = _gcry_ac_init ();
if (err)
goto fail;
}
#endif
return;
@ -235,6 +236,9 @@ gcry_check_version( const char *req_version )
int rq_major, rq_minor, rq_micro;
const char *my_plvl;
if (req_version && req_version[0] == 1 && req_version[1] == 1)
return _gcry_compat_identification ();
/* Initialize library. */
global_init ();
@ -292,7 +296,6 @@ print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
#endif
"\n");
fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
fnc (fp, "threads:%s:\n", ath_get_model (NULL));
hwf = _gcry_get_hw_features ();
fnc (fp, "hwflist:");
for (i=0; hwflist[i].desc; i++)
@ -444,8 +447,8 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
break;
case GCRYCTL_SET_THREAD_CBS:
err = ath_install (va_arg (arg_ptr, void *));
if (!err)
err = ath_install (va_arg (arg_ptr, void *), any_init_done);
if (! err)
global_init ();
break;
@ -596,9 +599,17 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
}
break;
case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
if (!any_init_done)
{
/* Not yet intialized at all. Set the enforced fips mode flag */
_gcry_set_enforced_fips_mode ();
}
else
err = GPG_ERR_GENERAL;
break;
default:
/* A call to make sure that the dummy code is linked in. */
_gcry_compat_identification ();
err = GPG_ERR_INV_OP;
}

View file

@ -766,8 +766,6 @@ main (int argc, char **argv)
pgm, strerror (errno));
exit (1);
}
if (use_stdin)
break;
}
else
{

View file

@ -132,8 +132,7 @@ EXPORTS
gcry_cipher_decrypt @101
gcry_cipher_get_algo_keylen @102
gcry_cipher_get_algo_blklen @103
;; @104 used to be part of the module register interface
gcry_cipher_list @104
gcry_pk_encrypt @105
gcry_pk_decrypt @106
@ -147,13 +146,33 @@ EXPORTS
gcry_pk_map_name @114
gcry_pk_get_nbits @115
gcry_pk_get_keygrip @116
gcry_pk_list @117
;; @117 used to be part of the module register interface
;;
;; 118 to 142 were used in previous Libgcrypt versions for the gcry_ac
;; interface
;;
gcry_ac_data_new @118
gcry_ac_data_destroy @119
gcry_ac_data_set @120
gcry_ac_data_copy @121
gcry_ac_data_length @122
gcry_ac_data_get_name @123
gcry_ac_data_get_index @124
gcry_ac_data_clear @125
gcry_ac_open @126
gcry_ac_close @127
gcry_ac_key_init @128
gcry_ac_key_pair_generate @129
gcry_ac_key_pair_extract @130
gcry_ac_key_data_get @131
gcry_ac_key_test @132
gcry_ac_key_get_nbits @133
gcry_ac_key_get_grip @134
gcry_ac_key_destroy @135
gcry_ac_key_pair_destroy @136
gcry_ac_data_encrypt @137
gcry_ac_data_decrypt @138
gcry_ac_data_sign @139
gcry_ac_data_verify @140
gcry_ac_id_to_name @141
gcry_ac_name_to_id @142
gcry_md_open @143
gcry_md_close @144
@ -173,7 +192,8 @@ EXPORTS
gcry_md_algo_name @158
gcry_md_map_name @159
gcry_md_setkey @160
;; @161 used to be part of the module register interface
gcry_md_list @161
gcry_randomize @162
gcry_random_add_bytes @163
gcry_random_bytes @164
@ -189,15 +209,21 @@ EXPORTS
gcry_md_debug @172
;; @173 used to be part of the module register interface
;; @174 used to be part of the module register interface
;; @175 used to be part of the module register interface
;; @176 used to be part of the module register interface
;; @177 used to be part of the module register interface
;; @178 used to be part of the module register interface
;;
;; @179 to @186 used to be part of the removed gcry_ac interface
;;
gcry_cipher_register @173
gcry_cipher_unregister @174
gcry_md_register @175
gcry_md_unregister @176
gcry_pk_register @177
gcry_pk_unregister @178
gcry_ac_data_from_sexp @179
gcry_ac_data_to_sexp @180
gcry_ac_io_init @181
gcry_ac_io_init_va @182
gcry_ac_data_encrypt_scheme @183
gcry_ac_data_decrypt_scheme @184
gcry_ac_data_sign_scheme @185
gcry_ac_data_verify_scheme @186
gcry_sexp_nth_string @187

View file

@ -1,5 +1,5 @@
dnl Autoconf macros for libgcrypt
dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc.
dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc.
dnl
dnl This file is free software; as a special exception the author gives
dnl unlimited permission to copy and/or distribute it, with or without
@ -21,8 +21,7 @@ dnl this features allows to prevent build against newer versions of libgcrypt
dnl with a changed API.
dnl
AC_DEFUN([AM_PATH_LIBGCRYPT],
[ AC_REQUIRE([AC_CANONICAL_HOST])
AC_ARG_WITH(libgcrypt-prefix,
[ AC_ARG_WITH(libgcrypt-prefix,
AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
[prefix where LIBGCRYPT is installed (optional)]),
libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
@ -99,9 +98,10 @@ AC_DEFUN([AM_PATH_LIBGCRYPT],
LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
ifelse([$2], , :, [$2])
libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
if test x"$libgcrypt_config_host" != xnone ; then
if test x"$libgcrypt_config_host" != x"$host" ; then
if test x"$host" != x ; then
libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
if test x"$libgcrypt_config_host" != xnone ; then
if test x"$libgcrypt_config_host" != x"$host" ; then
AC_MSG_WARN([[
***
*** The config script $LIBGCRYPT_CONFIG was
@ -110,6 +110,7 @@ AC_DEFUN([AM_PATH_LIBGCRYPT],
*** You may want to use the configure option --with-libgcrypt-prefix
*** to specify a matching config script.
***]])
fi
fi
fi
else

View file

@ -1,5 +1,5 @@
# libgcrypt.vers - What symbols to export -*- std -*-
# Copyright (C) 2002, 2004, 2008, 2011 Free Software Foundation, Inc.
# Copyright (C) 2002, 2004, 2008 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
@ -20,7 +20,7 @@
# NOTE: When adding new functions, please make sure to add them to
# visibility.h and libgcrypt.def as well.
GCRYPT_1.6 {
GCRYPT_1.2 {
global:
gcry_check_version; gcry_control;
gcry_set_allocation_handler; gcry_set_fatalerror_handler;
@ -40,24 +40,41 @@ GCRYPT_1.6 {
gcry_md_copy; gcry_md_ctl; gcry_md_enable; gcry_md_get;
gcry_md_get_algo; gcry_md_get_algo_dlen; gcry_md_hash_buffer;
gcry_md_info; gcry_md_is_enabled; gcry_md_is_secure;
gcry_md_map_name; gcry_md_open; gcry_md_read;
gcry_md_reset; gcry_md_setkey;
gcry_md_write; gcry_md_debug;
gcry_md_list; gcry_md_map_name; gcry_md_open; gcry_md_read;
gcry_md_register; gcry_md_reset; gcry_md_setkey;
gcry_md_unregister; gcry_md_write; gcry_md_debug;
gcry_cipher_algo_info; gcry_cipher_algo_name; gcry_cipher_close;
gcry_cipher_ctl; gcry_cipher_decrypt; gcry_cipher_encrypt;
gcry_cipher_get_algo_blklen; gcry_cipher_get_algo_keylen;
gcry_cipher_info; gcry_cipher_map_name;
gcry_cipher_info; gcry_cipher_list; gcry_cipher_map_name;
gcry_cipher_mode_from_oid; gcry_cipher_open;
gcry_cipher_register; gcry_cipher_unregister;
gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr;
gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl;
gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey;
gcry_pk_get_keygrip; gcry_pk_get_nbits;
gcry_pk_get_keygrip; gcry_pk_get_nbits; gcry_pk_list;
gcry_pk_map_name; gcry_pk_register; gcry_pk_sign;
gcry_pk_testkey; gcry_pk_verify;
gcry_pk_testkey; gcry_pk_unregister; gcry_pk_verify;
gcry_pk_get_curve; gcry_pk_get_param;
gcry_ac_data_new; gcry_ac_data_destroy; gcry_ac_data_copy;
gcry_ac_data_length; gcry_ac_data_clear; gcry_ac_data_set;
gcry_ac_data_get_name; gcry_ac_data_get_index; gcry_ac_open;
gcry_ac_close; gcry_ac_key_init; gcry_ac_key_pair_generate;
gcry_ac_key_pair_extract; gcry_ac_key_data_get; gcry_ac_key_test;
gcry_ac_key_get_nbits; gcry_ac_key_get_grip; gcry_ac_key_destroy;
gcry_ac_key_pair_destroy; gcry_ac_data_encrypt; gcry_ac_data_decrypt;
gcry_ac_data_sign; gcry_ac_data_verify; gcry_ac_id_to_name;
gcry_ac_name_to_id; gcry_ac_list; gcry_ac_data_encode;
gcry_ac_data_decode; gcry_ac_mpi_to_os; gcry_ac_mpi_to_os_alloc;
gcry_ac_os_to_mpi; gcry_ac_data_encrypt_scheme;
gcry_ac_data_decrypt_scheme;
gcry_ac_data_sign_scheme; gcry_ac_data_verify_scheme;
gcry_ac_data_to_sexp; gcry_ac_data_from_sexp;
gcry_ac_io_init; gcry_ac_io_init_va;
gcry_kdf_derive;
gcry_prime_check; gcry_prime_generate;

View file

@ -96,7 +96,7 @@ struct gcry_mpi
# define mpi_alloc_secure(n) _gcry_mpi_alloc_secure((n) )
# define mpi_free(a) _gcry_mpi_free((a) )
# define mpi_resize(a,b) _gcry_mpi_resize((a),(b))
# define mpi_copy(a) gcry_mpi_copy((a))
# define mpi_copy(a) _gcry_mpi_copy((a))
gcry_mpi_t _gcry_mpi_alloc( unsigned nlimbs );
gcry_mpi_t _gcry_mpi_alloc_secure( unsigned nlimbs );
void _gcry_mpi_free( gcry_mpi_t a );
@ -104,6 +104,8 @@ struct gcry_mpi
gcry_mpi_t _gcry_mpi_copy( gcry_mpi_t a );
#endif
#define gcry_mpi_copy _gcry_mpi_copy
#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
#define mpi_is_secure(a) ((a) && ((a)->flags&1))
#define mpi_clear(a) _gcry_mpi_clear ((a))
@ -114,13 +116,14 @@ struct gcry_mpi
#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a))
#define mpi_m_check(a) _gcry_mpi_m_check ((a))
#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b))
#define mpi_new(n) gcry_mpi_new ((n))
#define mpi_new(n) _gcry_mpi_new ((n))
#define mpi_snew(n) _gcry_mpi_snew ((n))
void _gcry_mpi_clear( gcry_mpi_t a );
gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a );
gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u);
gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
gcry_err_code_t gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
void _gcry_mpi_m_check( gcry_mpi_t a );
void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
gcry_mpi_t _gcry_mpi_new (unsigned int nbits);

View file

@ -576,13 +576,25 @@ gcry_sexp_nth( const gcry_sexp_t list, int number )
p++;
if ( *p == ST_DATA ) {
memcpy ( &n, p, sizeof n ); p += sizeof n;
newlist = gcry_malloc ( sizeof *newlist + n + 1 );
memcpy ( &n, p, sizeof n );
/* Allocate 1 (=sizeof *newlist) byte for ST_OPEN
1 byte for ST_DATA
sizeof n byte for n
n byte for the data
1 byte for ST_CLOSE
1 byte for ST_STOP */
newlist = gcry_malloc ( sizeof *newlist + 1 + sizeof n + n + 2 );
if (!newlist)
return NULL;
d = newlist->d;
memcpy ( d, p, n ); d += n;
*d++ = ST_STOP;
return NULL;
d = newlist->d;
*d = ST_OPEN; /* Put the ST_OPEN flag */
d++; /* Move forward */
/* Copy ST_DATA, n and the data from p to d */
memcpy ( d, p, 1 + sizeof n + n );
d += 1 + sizeof n + n; /* Move after the data copied */
*d = ST_CLOSE; /* Put the ST_CLOSE flag */
d++; /* Move forward */
*d = ST_STOP; /* Put the ST_STOP flag */
}
else if ( *p == ST_OPEN ) {
const byte *head = p;

View file

@ -18,7 +18,7 @@
VS_VERSION_INFO VERSIONINFO
FILEVERSION @LIBGCRYPT_LT_CURRENT@,@LIBGCRYPT_LT_AGE@,@LIBGCRYPT_LT_REVISION@,@BUILD_REVISION@
FILEVERSION @BUILD_FILEVERSION@
PRODUCTVERSION @BUILD_FILEVERSION@
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
@ -39,7 +39,7 @@ BEGIN
VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0"
VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT@.@LIBGCRYPT_LT_AGE@.@LIBGCRYPT_LT_REVISION@.@BUILD_REVISION@\0"
VALUE "InternalName", "libgcrypt\0"
VALUE "LegalCopyright", "Copyright © 2011 Free Software Foundation, Inc.\0"
VALUE "LegalCopyright", "Copyright © 2012 Free Software Foundation, Inc.\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "libgcrypt.dll\0"
VALUE "PrivateBuild", "\0"

View file

@ -621,6 +621,12 @@ gcry_cipher_get_algo_blklen (int algo)
return _gcry_cipher_get_algo_blklen (algo);
}
gcry_error_t
gcry_cipher_list (int *list, int *list_length)
{
return _gcry_cipher_list (list, list_length);
}
gcry_error_t
gcry_pk_encrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t pkey)
{
@ -753,6 +759,12 @@ gcry_pk_get_param (int algo, const char *name)
return _gcry_pk_get_param (algo, name);
}
gcry_error_t
gcry_pk_list (int *list, int *list_length)
{
return _gcry_pk_list (list, list_length);
}
gcry_error_t
gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
{
@ -910,6 +922,294 @@ gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
_gcry_md_debug (hd, suffix);
}
gcry_error_t
gcry_md_list (int *list, int *list_length)
{
return _gcry_md_list (list, list_length);
}
gcry_error_t
gcry_ac_data_new (gcry_ac_data_t *data)
{
return _gcry_ac_data_new (data);
}
void
gcry_ac_data_destroy (gcry_ac_data_t data)
{
_gcry_ac_data_destroy (data);
}
gcry_error_t
gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
{
return _gcry_ac_data_copy (data_cp, data);
}
unsigned int
gcry_ac_data_length (gcry_ac_data_t data)
{
return _gcry_ac_data_length (data);
}
void
gcry_ac_data_clear (gcry_ac_data_t data)
{
_gcry_ac_data_clear (data);
}
gcry_error_t
gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
const char *name, gcry_mpi_t mpi)
{
return _gcry_ac_data_set (data, flags, name, mpi);
}
gcry_error_t
gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
const char *name, gcry_mpi_t *mpi)
{
return _gcry_ac_data_get_name (data, flags, name, mpi);
}
gcry_error_t
gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
unsigned int idx, const char **name, gcry_mpi_t *mpi)
{
return _gcry_ac_data_get_index (data, flags, idx, name, mpi);
}
gcry_error_t
gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
const char **identifiers)
{
return _gcry_ac_data_to_sexp (data, sexp, identifiers);
}
gcry_error_t
gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
const char **identifiers)
{
return _gcry_ac_data_from_sexp (data, sexp, identifiers);
}
void
gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
gcry_ac_io_type_t type, ...)
{
va_list arg_ptr;
va_start (arg_ptr, type);
_gcry_ac_io_init_va (ac_io, mode, type, arg_ptr);
va_end (arg_ptr);
}
void
gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
gcry_ac_io_type_t type, va_list ap)
{
_gcry_ac_io_init_va (ac_io, mode, type, ap);
}
gcry_error_t
gcry_ac_open (gcry_ac_handle_t *handle,
gcry_ac_id_t algorithm, unsigned int flags)
{
return _gcry_ac_open (handle, algorithm, flags);
}
void
gcry_ac_close (gcry_ac_handle_t handle)
{
_gcry_ac_close (handle);
}
gcry_error_t
gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
gcry_ac_key_type_t type, gcry_ac_data_t data)
{
return _gcry_ac_key_init (key, handle, type, data);
}
gcry_error_t
gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
unsigned int nbits, void *spec,
gcry_ac_key_pair_t *key_pair,
gcry_mpi_t **miscdata)
{
return _gcry_ac_key_pair_generate ( handle, nbits, spec, key_pair, miscdata);
}
gcry_ac_key_t
gcry_ac_key_pair_extract (gcry_ac_key_pair_t keypair, gcry_ac_key_type_t which)
{
return _gcry_ac_key_pair_extract (keypair, which);
}
gcry_ac_data_t
gcry_ac_key_data_get (gcry_ac_key_t key)
{
return _gcry_ac_key_data_get (key);
}
gcry_error_t
gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
{
return _gcry_ac_key_test (handle, key);
}
gcry_error_t
gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
gcry_ac_key_t key, unsigned int *nbits)
{
return _gcry_ac_key_get_nbits (handle, key, nbits);
}
gcry_error_t
gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
unsigned char *key_grip)
{
return _gcry_ac_key_get_grip (handle, key, key_grip);
}
void
gcry_ac_key_destroy (gcry_ac_key_t key)
{
_gcry_ac_key_destroy (key);
}
void
gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
{
_gcry_ac_key_pair_destroy (key_pair);
}
gcry_error_t
gcry_ac_data_encode (gcry_ac_em_t method, unsigned int flags, void *options,
gcry_ac_io_t *io_read, gcry_ac_io_t *io_write)
{
return _gcry_ac_data_encode (method, flags, options, io_read, io_write);
}
gcry_error_t
gcry_ac_data_decode (gcry_ac_em_t method, unsigned int flags, void *options,
gcry_ac_io_t *io_read, gcry_ac_io_t *io_write)
{
return _gcry_ac_data_decode (method, flags, options, io_read, io_write);
}
gcry_error_t
gcry_ac_data_encrypt (gcry_ac_handle_t handle,
unsigned int flags,
gcry_ac_key_t key,
gcry_mpi_t data_plain,
gcry_ac_data_t *data_encrypted)
{
return _gcry_ac_data_encrypt (handle, flags, key,
data_plain, data_encrypted);
}
gcry_error_t
gcry_ac_data_decrypt (gcry_ac_handle_t handle,
unsigned int flags,
gcry_ac_key_t key,
gcry_mpi_t *data_plain,
gcry_ac_data_t data_encrypted)
{
return _gcry_ac_data_decrypt (handle, flags, key,
data_plain, data_encrypted);
}
gcry_error_t
gcry_ac_data_sign (gcry_ac_handle_t handle,
gcry_ac_key_t key,
gcry_mpi_t data,
gcry_ac_data_t *data_signature)
{
return _gcry_ac_data_sign (handle, key, data, data_signature);
}
gcry_error_t
gcry_ac_data_verify (gcry_ac_handle_t handle,
gcry_ac_key_t key,
gcry_mpi_t data,
gcry_ac_data_t data_signature)
{
return _gcry_ac_data_verify (handle, key, data, data_signature);
}
gcry_error_t
gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_message,
gcry_ac_io_t *io_cipher)
{
return _gcry_ac_data_encrypt_scheme (handle, scheme, flags, opts, key,
io_message, io_cipher);
}
gcry_error_t
gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_cipher,
gcry_ac_io_t *io_message)
{
return _gcry_ac_data_decrypt_scheme (handle, scheme, flags, opts, key,
io_cipher, io_message);
}
gcry_error_t
gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_message,
gcry_ac_io_t *io_signature)
{
return _gcry_ac_data_sign_scheme (handle, scheme, flags, opts, key,
io_message, io_signature);
}
gcry_error_t
gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_message,
gcry_ac_io_t *io_signature)
{
return _gcry_ac_data_verify_scheme (handle, scheme, flags, opts, key,
io_message, io_signature);
}
gcry_error_t
gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name)
{
/* This function is deprecated. We implement it in terms of the
suggested replacement. */
const char *tmp = _gcry_pk_algo_name (algorithm);
if (!*tmp)
return gcry_error (GPG_ERR_PUBKEY_ALGO);
*name = tmp;
return 0;
}
gcry_error_t
gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm)
{
/* This function is deprecated. We implement it in terms of the
suggested replacement. */
int algo = _gcry_pk_map_name (name);
if (!algo)
return gcry_error (GPG_ERR_PUBKEY_ALGO);
*algorithm = algo;
return 0;
}
gpg_error_t
gcry_kdf_derive (const void *passphrase, size_t passphraselen,
int algo, int hashalgo,
@ -1144,3 +1444,43 @@ gcry_is_secure (const void *a)
{
return _gcry_is_secure (a);
}
gcry_error_t
gcry_cipher_register (gcry_cipher_spec_t *cipher, int *algorithm_id,
gcry_module_t *module)
{
return _gcry_cipher_register (cipher, NULL, algorithm_id, module);
}
void
gcry_cipher_unregister (gcry_module_t module)
{
_gcry_cipher_unregister (module);
}
gcry_error_t
gcry_pk_register (gcry_pk_spec_t *pubkey, unsigned int *algorithm_id,
gcry_module_t *module)
{
return _gcry_pk_register (pubkey, NULL, algorithm_id, module);
}
void
gcry_pk_unregister (gcry_module_t module)
{
_gcry_pk_unregister (module);
}
gcry_error_t
gcry_md_register (gcry_md_spec_t *digest, unsigned int *algorithm_id,
gcry_module_t *module)
{
return _gcry_md_register (digest, NULL, algorithm_id, module);
}
void
gcry_md_unregister (gcry_module_t module)
{
_gcry_md_unregister (module);
}

View file

@ -66,9 +66,12 @@
#define gcry_md_info _gcry_md_info
#define gcry_md_is_enabled _gcry_md_is_enabled
#define gcry_md_is_secure _gcry_md_is_secure
#define gcry_md_list _gcry_md_list
#define gcry_md_map_name _gcry_md_map_name
#define gcry_md_open _gcry_md_open
#define gcry_md_read _gcry_md_read
/* gcry_md_register and _gcry_md_register differ. */
#define gcry_md_unregister _gcry_md_unregister
#define gcry_md_reset _gcry_md_reset
#define gcry_md_setkey _gcry_md_setkey
#define gcry_md_write _gcry_md_write
@ -86,9 +89,12 @@
#define gcry_cipher_get_algo_blklen _gcry_cipher_get_algo_blklen
#define gcry_cipher_get_algo_keylen _gcry_cipher_get_algo_keylen
#define gcry_cipher_info _gcry_cipher_info
#define gcry_cipher_list _gcry_cipher_list
#define gcry_cipher_map_name _gcry_cipher_map_name
#define gcry_cipher_mode_from_oid _gcry_cipher_mode_from_oid
#define gcry_cipher_open _gcry_cipher_open
/* gcry_cipher_register and _gcry_cipher_register differ. */
#define gcry_cipher_unregister _gcry_cipher_unregister
#define gcry_pk_algo_info _gcry_pk_algo_info
#define gcry_pk_algo_name _gcry_pk_algo_name
@ -100,11 +106,53 @@
#define gcry_pk_get_curve _gcry_pk_get_curve
#define gcry_pk_get_param _gcry_pk_get_param
#define gcry_pk_get_nbits _gcry_pk_get_nbits
#define gcry_pk_list _gcry_pk_list
#define gcry_pk_map_name _gcry_pk_map_name
/* gcry_pk_register and _gcry_pk_register differ. */
#define gcry_pk_unregister _gcry_pk_unregister
#define gcry_pk_sign _gcry_pk_sign
#define gcry_pk_testkey _gcry_pk_testkey
#define gcry_pk_verify _gcry_pk_verify
#define gcry_ac_data_new _gcry_ac_data_new
#define gcry_ac_data_destroy _gcry_ac_data_destroy
#define gcry_ac_data_copy _gcry_ac_data_copy
#define gcry_ac_data_length _gcry_ac_data_length
#define gcry_ac_data_clear _gcry_ac_data_clear
#define gcry_ac_data_set _gcry_ac_data_set
#define gcry_ac_data_get_name _gcry_ac_data_get_name
#define gcry_ac_data_get_index _gcry_ac_data_get_index
#define gcry_ac_open _gcry_ac_open
#define gcry_ac_close _gcry_ac_close
#define gcry_ac_key_init _gcry_ac_key_init
#define gcry_ac_key_pair_generate _gcry_ac_key_pair_generate
#define gcry_ac_key_pair_extract _gcry_ac_key_pair_extract
#define gcry_ac_key_data_get _gcry_ac_key_data_get
#define gcry_ac_key_test _gcry_ac_key_test
#define gcry_ac_key_get_nbits _gcry_ac_key_get_nbits
#define gcry_ac_key_get_grip _gcry_ac_key_get_grip
#define gcry_ac_key_destroy _gcry_ac_key_destroy
#define gcry_ac_key_pair_destroy _gcry_ac_key_pair_destroy
#define gcry_ac_data_encrypt _gcry_ac_data_encrypt
#define gcry_ac_data_decrypt _gcry_ac_data_decrypt
#define gcry_ac_data_sign _gcry_ac_data_sign
#define gcry_ac_data_verify _gcry_ac_data_verify
#define gcry_ac_id_to_name _gcry_ac_id_to_name
#define gcry_ac_name_to_id _gcry_ac_name_to_id
#define gcry_ac_data_encode _gcry_ac_data_encode
#define gcry_ac_data_decode _gcry_ac_data_decode
#define gcry_ac_mpi_to_os _gcry_ac_mpi_to_os
#define gcry_ac_mpi_to_os_alloc _gcry_ac_mpi_to_os_alloc
#define gcry_ac_os_to_mpi _gcry_ac_os_to_mpi
#define gcry_ac_data_encrypt_scheme _gcry_ac_data_encrypt_scheme
#define gcry_ac_data_decrypt_scheme _gcry_ac_data_decrypt_scheme
#define gcry_ac_data_sign_scheme _gcry_ac_data_sign_scheme
#define gcry_ac_data_verify_scheme _gcry_ac_data_verify_scheme
#define gcry_ac_data_to_sexp _gcry_ac_data_to_sexp
#define gcry_ac_data_from_sexp _gcry_ac_data_from_sexp
#define gcry_ac_io_init _gcry_ac_io_init
#define gcry_ac_io_init_va _gcry_ac_io_init_va
#define gcry_kdf_derive _gcry_kdf_derive
#define gcry_prime_check _gcry_prime_check
@ -193,15 +241,111 @@
deprecated attribute. */
# define GCRYPT_NO_DEPRECATED
# include "gcrypt.h"
/* None in this version. */
/* The algorithm IDs. */
gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data);
void gcry_ac_data_destroy (gcry_ac_data_t data);
gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
gcry_ac_data_t data);
unsigned int gcry_ac_data_length (gcry_ac_data_t data);
void gcry_ac_data_clear (gcry_ac_data_t data);
gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
const char *name, gcry_mpi_t mpi);
gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
const char *name, gcry_mpi_t *mpi);
gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
unsigned int idx,
const char **name, gcry_mpi_t *mpi);
gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
const char **identifiers);
gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
const char **identifiers);
void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
gcry_ac_io_type_t type, ...);
void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
gcry_ac_io_type_t type, va_list ap);
gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
gcry_ac_id_t algorithm, unsigned int flags);
void gcry_ac_close (gcry_ac_handle_t handle);
gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
gcry_ac_key_type_t type, gcry_ac_data_t data);
gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
unsigned int nbits, void *spec,
gcry_ac_key_pair_t *key_pair,
gcry_mpi_t **misc_data);
gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
gcry_ac_key_type_t which);
gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key);
gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key);
gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
gcry_ac_key_t key, unsigned int *nbits);
gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
unsigned char *key_grip);
void gcry_ac_key_destroy (gcry_ac_key_t key);
void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair);
gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
unsigned int flags, void *options,
gcry_ac_io_t *io_read,
gcry_ac_io_t *io_write);
gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
unsigned int flags, void *options,
gcry_ac_io_t *io_read,
gcry_ac_io_t *io_write);
gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
unsigned int flags,
gcry_ac_key_t key,
gcry_mpi_t data_plain,
gcry_ac_data_t *data_encrypted);
gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
unsigned int flags,
gcry_ac_key_t key,
gcry_mpi_t *data_plain,
gcry_ac_data_t data_encrypted);
gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
gcry_ac_key_t key,
gcry_mpi_t data,
gcry_ac_data_t *data_signature);
gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
gcry_ac_key_t key,
gcry_mpi_t data,
gcry_ac_data_t data_signature);
gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_message,
gcry_ac_io_t *io_cipher);
gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_cipher,
gcry_ac_io_t *io_message);
gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_message,
gcry_ac_io_t *io_signature);
gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
gcry_ac_scheme_t scheme,
unsigned int flags, void *opts,
gcry_ac_key_t key,
gcry_ac_io_t *io_message,
gcry_ac_io_t *io_signature);
gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name);
gcry_error_t gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm);
#else
# include "gcrypt.h"
#endif
#include "gcrypt-module.h"
/* Prototypes of functions exported but not ready for use. */
gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
unsigned char *buffer, int buflen);
void gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n);
gcry_error_t gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os,
size_t *os_n);
void gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n);
/* Our use of the ELF visibility feature works by passing
@ -272,9 +416,12 @@ gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
#undef gcry_md_info
#undef gcry_md_is_enabled
#undef gcry_md_is_secure
#undef gcry_md_list
#undef gcry_md_map_name
#undef gcry_md_open
#undef gcry_md_read
/* gcry_md_register is not anymore a macro. */
#undef gcry_md_unregister
#undef gcry_md_reset
#undef gcry_md_setkey
#undef gcry_md_write
@ -292,9 +439,12 @@ gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
#undef gcry_cipher_get_algo_blklen
#undef gcry_cipher_get_algo_keylen
#undef gcry_cipher_info
#undef gcry_cipher_list
#undef gcry_cipher_map_name
#undef gcry_cipher_mode_from_oid
#undef gcry_cipher_open
/* gcry_cipher_register is not anymore a macro. */
#undef gcry_cipher_unregister
#undef gcry_pk_algo_info
#undef gcry_pk_algo_name
@ -306,11 +456,53 @@ gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
#undef gcry_pk_get_curve
#undef gcry_pk_get_param
#undef gcry_pk_get_nbits
#undef gcry_pk_list
#undef gcry_pk_map_name
/* gcry_pk_register is not anymore a macro. */
#undef gcry_pk_unregister
#undef gcry_pk_sign
#undef gcry_pk_testkey
#undef gcry_pk_verify
#undef gcry_ac_data_new
#undef gcry_ac_data_destroy
#undef gcry_ac_data_copy
#undef gcry_ac_data_length
#undef gcry_ac_data_clear
#undef gcry_ac_data_set
#undef gcry_ac_data_get_name
#undef gcry_ac_data_get_index
#undef gcry_ac_open
#undef gcry_ac_close
#undef gcry_ac_key_init
#undef gcry_ac_key_pair_generate
#undef gcry_ac_key_pair_extract
#undef gcry_ac_key_data_get
#undef gcry_ac_key_test
#undef gcry_ac_key_get_nbits
#undef gcry_ac_key_get_grip
#undef gcry_ac_key_destroy
#undef gcry_ac_key_pair_destroy
#undef gcry_ac_data_encrypt
#undef gcry_ac_data_decrypt
#undef gcry_ac_data_sign
#undef gcry_ac_data_verify
#undef gcry_ac_id_to_name
#undef gcry_ac_name_to_id
#undef gcry_ac_data_encode
#undef gcry_ac_data_decode
#undef gcry_ac_mpi_to_os
#undef gcry_ac_mpi_to_os_alloc
#undef gcry_ac_os_to_mpi
#undef gcry_ac_data_encrypt_scheme
#undef gcry_ac_data_decrypt_scheme
#undef gcry_ac_data_sign_scheme
#undef gcry_ac_data_verify_scheme
#undef gcry_ac_data_to_sexp
#undef gcry_ac_data_from_sexp
#undef gcry_ac_io_init
#undef gcry_ac_io_init_va
#undef gcry_kdf_derive
#undef gcry_prime_check
@ -438,11 +630,14 @@ MARK_VISIBLE (gcry_md_hash_buffer)
MARK_VISIBLE (gcry_md_info)
MARK_VISIBLE (gcry_md_is_enabled)
MARK_VISIBLE (gcry_md_is_secure)
MARK_VISIBLE (gcry_md_list)
MARK_VISIBLE (gcry_md_map_name)
MARK_VISIBLE (gcry_md_open)
MARK_VISIBLE (gcry_md_read)
MARK_VISIBLEX(gcry_md_register)
MARK_VISIBLE (gcry_md_reset)
MARK_VISIBLE (gcry_md_setkey)
MARK_VISIBLE (gcry_md_unregister)
MARK_VISIBLE (gcry_md_write)
MARK_VISIBLE (gcry_md_debug)
@ -458,9 +653,12 @@ MARK_VISIBLE (gcry_cipher_encrypt)
MARK_VISIBLE (gcry_cipher_get_algo_blklen)
MARK_VISIBLE (gcry_cipher_get_algo_keylen)
MARK_VISIBLE (gcry_cipher_info)
MARK_VISIBLE (gcry_cipher_list)
MARK_VISIBLE (gcry_cipher_map_name)
MARK_VISIBLE (gcry_cipher_mode_from_oid)
MARK_VISIBLE (gcry_cipher_open)
MARK_VISIBLEX(gcry_cipher_register)
MARK_VISIBLE (gcry_cipher_unregister)
MARK_VISIBLE (gcry_pk_algo_info)
MARK_VISIBLE (gcry_pk_algo_name)
@ -472,11 +670,55 @@ MARK_VISIBLE (gcry_pk_get_keygrip)
MARK_VISIBLE (gcry_pk_get_curve)
MARK_VISIBLE (gcry_pk_get_param)
MARK_VISIBLE (gcry_pk_get_nbits)
MARK_VISIBLE (gcry_pk_list)
MARK_VISIBLE (gcry_pk_map_name)
MARK_VISIBLEX(gcry_pk_register)
MARK_VISIBLE (gcry_pk_sign)
MARK_VISIBLE (gcry_pk_testkey)
MARK_VISIBLE (gcry_pk_unregister)
MARK_VISIBLE (gcry_pk_verify)
MARK_VISIBLE (gcry_ac_data_new)
MARK_VISIBLE (gcry_ac_data_destroy)
MARK_VISIBLE (gcry_ac_data_copy)
MARK_VISIBLE (gcry_ac_data_length)
MARK_VISIBLE (gcry_ac_data_clear)
MARK_VISIBLE (gcry_ac_data_set)
MARK_VISIBLE (gcry_ac_data_get_name)
MARK_VISIBLE (gcry_ac_data_get_index)
MARK_VISIBLE (gcry_ac_open)
MARK_VISIBLE (gcry_ac_close)
MARK_VISIBLE (gcry_ac_key_init)
MARK_VISIBLE (gcry_ac_key_pair_generate)
MARK_VISIBLE (gcry_ac_key_pair_extract)
MARK_VISIBLE (gcry_ac_key_data_get)
MARK_VISIBLE (gcry_ac_key_test)
MARK_VISIBLE (gcry_ac_key_get_nbits)
MARK_VISIBLE (gcry_ac_key_get_grip)
MARK_VISIBLE (gcry_ac_key_destroy)
MARK_VISIBLE (gcry_ac_key_pair_destroy)
MARK_VISIBLE (gcry_ac_data_encrypt)
MARK_VISIBLE (gcry_ac_data_decrypt)
MARK_VISIBLE (gcry_ac_data_sign)
MARK_VISIBLE (gcry_ac_data_verify)
MARK_VISIBLE (gcry_ac_id_to_name)
MARK_VISIBLE (gcry_ac_name_to_id)
/* MARK_VISIBLE (gcry_ac_list) Not defined although it is in
libgcrypt.vers. */
MARK_VISIBLE (gcry_ac_data_encode)
MARK_VISIBLE (gcry_ac_data_decode)
MARK_VISIBLE (gcry_ac_mpi_to_os)
MARK_VISIBLE (gcry_ac_mpi_to_os_alloc)
MARK_VISIBLE (gcry_ac_os_to_mpi)
MARK_VISIBLE (gcry_ac_data_encrypt_scheme)
MARK_VISIBLE (gcry_ac_data_decrypt_scheme)
MARK_VISIBLE (gcry_ac_data_sign_scheme)
MARK_VISIBLE (gcry_ac_data_verify_scheme)
MARK_VISIBLE (gcry_ac_data_to_sexp)
MARK_VISIBLE (gcry_ac_data_from_sexp)
MARK_VISIBLE (gcry_ac_io_init)
MARK_VISIBLE (gcry_ac_io_init_va)
MARK_VISIBLE (gcry_kdf_derive)
MARK_VISIBLE (gcry_prime_check)

View file

@ -27,6 +27,9 @@
#include <sys/types.h>
#define _gcry_mpi_invm gcry_mpi_invm
#define _gcry_mpi_set gcry_mpi_set
#define _gcry_mpi_set_ui gcry_mpi_set_ui
#define size_t grub_size_t
#undef __GNU_LIBRARY__
@ -48,11 +51,13 @@ selftest (void)
}
static inline int
fips_mode (void)
_gcry_fips_mode (void)
{
return 0;
}
#define assert gcry_assert
#ifdef GRUB_UTIL
#define memset grub_memset

View file

@ -65,7 +65,8 @@ typedef enum
GPG_ERR_WRONG_KEY_USAGE,
GPG_ERR_WRONG_PUBKEY_ALGO,
GPG_ERR_OUT_OF_MEMORY,
GPG_ERR_TOO_LARGE
GPG_ERR_TOO_LARGE,
GPG_ERR_ENOMEM
} gpg_err_code_t;
typedef gpg_err_code_t gpg_error_t;
typedef gpg_error_t gcry_error_t;
@ -331,6 +332,7 @@ grub_md_unregister (gcry_md_spec_t *cipher);
extern struct gcry_pk_spec *grub_crypto_pk_dsa;
extern struct gcry_pk_spec *grub_crypto_pk_ecdsa;
extern struct gcry_pk_spec *grub_crypto_pk_ecdh;
extern struct gcry_pk_spec *grub_crypto_pk_rsa;
void

View file

@ -102,10 +102,10 @@ cryptolist.write ("CRC64: crc64\n");
for cipher_file in cipher_files:
infile = os.path.join (cipher_dir_in, cipher_file)
outfile = os.path.join (cipher_dir_out, cipher_file)
if cipher_file == "ChangeLog":
if cipher_file == "ChangeLog" or cipher_file == "ChangeLog-2011":
continue
chlognew = " * %s" % cipher_file
if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file) or cipher_file == "elgamal.c" or cipher_file == "primegen.c" or cipher_file == "test-getrusage.c":
if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file) or cipher_file == "kdf.c" or cipher_file == "elgamal.c" or cipher_file == "primegen.c" or cipher_file == "ecc.c" or cipher_file == "test-getrusage.c":
chlog = "%s%s: Removed\n" % (chlog, chlognew)
continue
# Autogenerated files. Not even worth mentionning in ChangeLog
@ -139,7 +139,7 @@ for cipher_file in cipher_files:
mdnames = []
pknames = []
hold = False
skip = False
skip = 0
skip2 = False
ismd = False
ispk = False
@ -160,9 +160,9 @@ for cipher_file in cipher_files:
if not re.search (";", line) is None:
skip_statement = False
continue
if skip:
if skip > 0:
if line[0] == "}":
skip = False
skip = skip - 1
continue
if skip2:
if not re.search (" *};", line) is None:
@ -195,7 +195,7 @@ for cipher_file in cipher_files:
# Used only for selftests.
m = re.match ("(static byte|static unsigned char) (weak_keys_chksum)\[[0-9]*\] =", line)
if not m is None:
skip = True
skip = 1
fname = m.groups ()[1]
chmsg = "(%s): Removed." % fname
if nch:
@ -209,7 +209,11 @@ for cipher_file in cipher_files:
# We're optimising for size and exclude anything needing good
# randomness.
if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info|_gcry_rmd160_mixblock|serpent_test|dsa_generate_ext|test_keys|gen_k|sign|gen_x931_parm_xp|generate_x931|generate_key|dsa_generate|dsa_sign|ecc_sign|generate|generate_fips186|_gcry_register_pk_dsa_progress|_gcry_register_pk_ecc_progress|progress|scanval|ec2os|ecc_generate_ext|ecc_generate|compute_keygrip|ecc_get_param|_gcry_register_pk_dsa_progress|gen_x931_parm_xp|gen_x931_parm_xi|rsa_decrypt|rsa_sign|rsa_generate_ext|rsa_generate|secret|check_exponent|rsa_blind|rsa_unblind|extract_a_from_sexp|curve_free|curve_copy|point_set)", line) is None:
skip = True
skip = 1
if not re.match ("selftest", line) is None and cipher_file == "idea.c":
skip = 3
if not re.match ("serpent_test", line) is None:
fw.write ("static const char *serpent_test (void) { return 0; }\n");
if not re.match ("dsa_generate", line) is None:
@ -343,9 +347,16 @@ for cipher_file in cipher_files:
holdline = line
continue
m = re.match ("static int tripledes_set2keys \(.*\);", line)
if not m is None:
continue
m = re.match ("static int tripledes_set3keys \(.*\);", line)
if not m is None:
continue
m = re.match ("static int tripledes_set2keys \(", line)
if not m is None:
skip_statement = True
continue
m = re.match ("static int tripledes_set3keys \(", line)
if not m is None:
skip_statement = True
continue
@ -451,7 +462,7 @@ for cipher_file in cipher_files:
conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare';\n")
elif modname == "gcry_rijndael" or modname == "gcry_md4" or modname == "gcry_md5" or modname == "gcry_rmd160" or modname == "gcry_sha1" or modname == "gcry_sha256" or modname == "gcry_sha512" or modname == "gcry_tiger":
# Alignment checked by hand
conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-cast-align -Wno-strict-aliasing';\n");
conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-cast-align';\n");
else:
conf.write (" cflags = '$(CFLAGS_GCRY)';\n");
conf.write (" cppflags = '$(CPPFLAGS_GCRY)';\n");
@ -522,18 +533,18 @@ for src in sorted (os.listdir (os.path.join (indir, "mpi"))):
fw.write ("/* This file was automatically imported with \n")
fw.write (" import_gcry.py. Please don't modify it */\n")
hold = False
skip = False
skip = 0
for line in f:
if skip:
if skip > 0:
if line[0] == "}":
skip = False
skip = skip - 1
continue
if hold:
hold = False
# We're optimising for size and exclude anything needing good
# randomness.
if not re.match ("(_gcry_mpi_get_hw_config|gcry_mpi_randomize)", line) is None:
skip = True
skip = 1
continue
else:
fw.write (holdline)

View file

@ -7,9 +7,12 @@
/^# *include <time\.h>/ d
/^# *include <sys\/socket\.h>/ d
/^# *include <sys\/time\.h>/ d
/^ typedef long ssize_t;/ d
/^ typedef int pid_t;/ d
/^# *include <gpg-error\.h>/ s,#include <gpg-error.h>,#include <grub/gcrypt/gpg-error.h>,
/^typedef gpg_error_t gcry_error_t;/ d
/^typedef gpg_err_code_t gcry_err_code_t;/ d
/^typedef struct gcry_mpi \*gcry_mpi_t;/ d
/^struct gcry_thread_cbs/ d
s,_gcry_mpi_invm,gcry_mpi_invm,g
p