summaryrefslogtreecommitdiff
path: root/mpi
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
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')
-rw-r--r--mpi/mpi-bit.c93
-rw-r--r--mpi/mpicoder.c6
-rw-r--r--mpi/mpiutil.c48
3 files changed, 117 insertions, 30 deletions
diff --git a/mpi/mpi-bit.c b/mpi/mpi-bit.c
index cdc6b0b3..74042e89 100644
--- a/mpi/mpi-bit.c
+++ b/mpi/mpi-bit.c
@@ -1,5 +1,6 @@
/* mpi-bit.c - MPI bit level functions
* Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -117,6 +118,12 @@ gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
{
unsigned int limbno, bitno;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
limbno = n / BITS_PER_MPI_LIMB;
bitno = n % BITS_PER_MPI_LIMB;
@@ -136,6 +143,12 @@ gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
{
unsigned int limbno, bitno;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
limbno = n / BITS_PER_MPI_LIMB;
bitno = n % BITS_PER_MPI_LIMB;
@@ -156,18 +169,23 @@ gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
void
gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
{
- unsigned int limbno, bitno;
+ unsigned int limbno, bitno;
- limbno = n / BITS_PER_MPI_LIMB;
- bitno = n % BITS_PER_MPI_LIMB;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
- if( limbno >= a->nlimbs )
- return; /* not allocated, therefore no need to clear bits
- :-) */
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return; /* not allocated, therefore no need to clear bits :-) */
- for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
- a->d[limbno] &= ~(A_LIMB_1 << bitno);
- a->nlimbs = limbno+1;
+ for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno+1;
}
/****************
@@ -176,14 +194,20 @@ gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
void
gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
{
- unsigned int limbno, bitno;
+ unsigned int limbno, bitno;
- limbno = n / BITS_PER_MPI_LIMB;
- bitno = n % BITS_PER_MPI_LIMB;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
- if( limbno >= a->nlimbs )
- return; /* don't need to clear this bit, it's to far to left */
- a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if (limbno >= a->nlimbs)
+ return; /* Don't need to clear this bit, it's far too left. */
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
}
@@ -194,19 +218,26 @@ gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
void
_gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
{
- mpi_ptr_t ap = a->d;
- mpi_size_t n = a->nlimbs;
- unsigned int i;
+ mpi_ptr_t ap = a->d;
+ mpi_size_t n = a->nlimbs;
+ unsigned int i;
- if( count >= n ) {
- a->nlimbs = 0;
- return;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
}
- for( i = 0; i < n - count; i++ )
- ap[i] = ap[i+count];
- ap[i] = 0;
- a->nlimbs -= count;
+ if (count >= n)
+ {
+ a->nlimbs = 0;
+ return;
+ }
+
+ for( i = 0; i < n - count; i++ )
+ ap[i] = ap[i+count];
+ ap[i] = 0;
+ a->nlimbs -= count;
}
@@ -221,6 +252,12 @@ gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+ if (mpi_is_immutable (x))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
if ( x == a )
{
/* In-place operation. */
@@ -328,6 +365,12 @@ gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+ if (mpi_is_immutable (x))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
if (x == a && !n)
return; /* In-place shift with an amount of zero. */
diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c
index a3435ed1..06d5553e 100644
--- a/mpi/mpicoder.c
+++ b/mpi/mpicoder.c
@@ -305,6 +305,12 @@ _gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
int nlimbs;
int i;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
RESIZE_IF_NEEDED(a, nlimbs);
a->sign = sign;
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*/