diff options
author | Werner Koch <wk@gnupg.org> | 2013-03-12 20:20:42 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-03-13 12:38:30 +0100 |
commit | 1fecae98ee7e0fa49b29f98efa6817ca121ed98a (patch) | |
tree | 02a3ba8f73f47d1ee629563d1abde0b56dc5d31d /mpi | |
parent | 5e743bc72e3fee3d550d0d7ae98596b7de6b46f8 (diff) | |
download | libgcrypt-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.c | 93 | ||||
-rw-r--r-- | mpi/mpicoder.c | 6 | ||||
-rw-r--r-- | mpi/mpiutil.c | 48 |
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*/ |