summaryrefslogtreecommitdiff
path: root/mpi/mpiutil.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-03-12 20:20:42 +0100
committerWerner Koch <wk@gnupg.org>2013-03-13 12:38:30 +0100
commit1fecae98ee7e0fa49b29f98efa6817ca121ed98a (patch)
tree02a3ba8f73f47d1ee629563d1abde0b56dc5d31d /mpi/mpiutil.c
parent5e743bc72e3fee3d550d0d7ae98596b7de6b46f8 (diff)
downloadlibgcrypt-1fecae98ee7e0fa49b29f98efa6817ca121ed98a.tar.gz
Add GCRYMPI_FLAG_IMMUTABLE to help debugging.
* src/gcrypt.h.in (GCRYMPI_FLAG_IMMUTABLE): New. * src/mpi.h (mpi_is_immutable): New macro. * mpi/mpiutil.c (gcry_mpi_set_flag, gcry_mpi_clear_flag) (gcry_mpi_get_flag): Implement new flag (_gcry_mpi_immutable_failed): New. * mpi/mpiutil.c (_gcry_mpi_clear, _gcry_mpi_free, gcry_mpi_snatch) (gcry_mpi_set, gcry_mpi_randomize): Act upon the immutable flag. * mpi/mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit) (gcry_mpi_clear_highbit, gcry_mpi_clear_bit) (_gcry_mpi_rshift_limbs, gcry_mpi_lshift): Ditto. * mpi/mpicoder.c (_gcry_mpi_set_buffer): Ditto. -- Note that this flag is currently only checked by a few MPI functions. The reason why we eventually need such a flag is to help implementing a generic way to retrieve and set ECC parameters without accidentally changing a curve parameter taken from a list of predefined curves.
Diffstat (limited to 'mpi/mpiutil.c')
-rw-r--r--mpi/mpiutil.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c
index d410d90b..64a2f7e1 100644
--- a/mpi/mpiutil.c
+++ b/mpi/mpiutil.c
@@ -163,8 +163,13 @@ _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
void
_gcry_mpi_clear( gcry_mpi_t a )
{
- a->nlimbs = 0;
- a->flags = 0;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+ a->nlimbs = 0;
+ a->flags = 0;
}
@@ -179,11 +184,21 @@ _gcry_mpi_free( gcry_mpi_t a )
{
_gcry_mpi_free_limb_space(a->d, a->alloced);
}
- if ((a->flags & ~7))
- log_bug("invalid flag value in mpi\n");
+ /* Check that the flags makes sense. We better allow for bit 1
+ (value 2) for backward ABI compatibility. */
+ if ((a->flags & ~(1|2|4|16)))
+ log_bug("invalid flag value in mpi_free\n");
gcry_free(a);
}
+
+void
+_gcry_mpi_immutable_failed (void)
+{
+ log_info ("Warning: trying to change immutable MPI\n");
+}
+
+
static void
mpi_set_secure( gcry_mpi_t a )
{
@@ -303,6 +318,11 @@ gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u)
{
if (w)
{
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
_gcry_mpi_assign_limb_space (w, u->d, u->alloced);
w->nlimbs = u->nlimbs;
w->sign = u->sign;
@@ -324,6 +344,11 @@ gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
if (!w)
w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return w;
+ }
RESIZE_IF_NEEDED(w, usize);
wp = w->d;
up = u->d;
@@ -342,6 +367,11 @@ gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u)
w = _gcry_mpi_alloc (1);
/* FIXME: If U is 0 we have no need to resize and thus possible
allocating the the limbs. */
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return w;
+ }
RESIZE_IF_NEEDED(w, 1);
w->d[0] = u;
w->nlimbs = u? 1:0;
@@ -426,6 +456,11 @@ gcry_mpi_randomize( gcry_mpi_t w,
unsigned char *p;
size_t nbytes = (nbits+7)/8;
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
if (level == GCRY_WEAK_RANDOM)
{
p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes)
@@ -446,7 +481,8 @@ void
gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
{
switch( flag ) {
- case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
+ case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
+ case GCRYMPI_FLAG_IMMUTABLE: a->flags |= 16; break;
case GCRYMPI_FLAG_OPAQUE:
default: log_bug("invalid flag value\n");
}
@@ -459,6 +495,7 @@ gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
switch (flag)
{
+ case GCRYMPI_FLAG_IMMUTABLE: a->flags &= ~16; break;
case GCRYMPI_FLAG_SECURE:
case GCRYMPI_FLAG_OPAQUE:
default: log_bug("invalid flag value\n");
@@ -472,6 +509,7 @@ gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
{
case GCRYMPI_FLAG_SECURE: return (a->flags & 1);
case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4);
+ case GCRYMPI_FLAG_IMMUTABLE: return (a->flags & 16);
default: log_bug("invalid flag value\n");
}
/*NOTREACHED*/