summaryrefslogtreecommitdiff
path: root/mpi/mpiutil.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-03-13 15:08:33 +0100
committerWerner Koch <wk@gnupg.org>2013-03-13 15:08:33 +0100
commite005629bd7bebb3e13945645c6e1230b44ab16a2 (patch)
tree46dc8a478d794e103ee4e70ec5c0832902d1bcba /mpi/mpiutil.c
parent1fecae98ee7e0fa49b29f98efa6817ca121ed98a (diff)
downloadlibgcrypt-e005629bd7bebb3e13945645c6e1230b44ab16a2.tar.gz
Add GCRYMPI_FLAG_CONST and make use constants.
* src/gcrypt.h.in (GCRYMPI_FLAG_CONST): New. * src/mpi.h (mpi_is_const, mpi_const): New. (enum gcry_mpi_constants, MPI_NUMBER_OF_CONSTANTS): New. * mpi/mpiutil.c (_gcry_mpi_init): New. (constants): New. (_gcry_mpi_free): Do not release a constant flagged MPI. (gcry_mpi_copy): Clear the const and immutable flags. (gcry_mpi_set_flag, gcry_mpi_clear_flag, gcry_mpi_get_flag): Support GCRYMPI_FLAG_CONST. (_gcry_mpi_const): New. * src/global.c (global_init): Call _gcry_mpi_init. * mpi/ec.c (mpi_ec_ctx_s): Remove fields one, two, three, four, and eight. Change all users to call mpi_const() instead. * src/mpiutils.c (gcry_mpi_set_opaque): Check the immutable flag. -- Allocating the trivial constants newly for every EC context is a waste of memory and cpu cycles. We instead provide a simple mechanism to internally support such constants. Using a new flag in THE API also allows to mark an arbitrary MPI as constant. The drawback of the constants is the their memory will never be deallocated. However, that is what constants are about.
Diffstat (limited to 'mpi/mpiutil.c')
-rw-r--r--mpi/mpiutil.c89
1 files changed, 76 insertions, 13 deletions
diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c
index 64a2f7e1..cff15b74 100644
--- a/mpi/mpiutil.c
+++ b/mpi/mpiutil.c
@@ -28,6 +28,10 @@
#include "mpi-internal.h"
#include "mod-source-info.h"
+/* Constatns allocated right away at strtartup. */
+static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS];
+
+
const char *
_gcry_mpi_get_hw_config (void)
@@ -36,6 +40,34 @@ _gcry_mpi_get_hw_config (void)
}
+/* Initialize the MPI subsystem. This is called early and allows to
+ do some initialization without taking care of threading issues. */
+gcry_err_code_t
+_gcry_mpi_init (void)
+{
+ int idx;
+ unsigned long value;
+
+ for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++)
+ {
+ switch (idx)
+ {
+ case MPI_C_ZERO: value = 0; break;
+ case MPI_C_ONE: value = 1; break;
+ case MPI_C_TWO: value = 2; break;
+ case MPI_C_THREE: value = 3; break;
+ case MPI_C_FOUR: value = 4; break;
+ case MPI_C_EIGHT: value = 8; break;
+ default: log_bug ("invalid mpi_const selector %d\n", idx);
+ }
+ constants[idx] = mpi_alloc_set_ui (value);
+ constants[idx]->flags = (16|32);
+ }
+
+ return 0;
+}
+
+
/****************
* Note: It was a bad idea to use the number of limbs to allocate
* because on a alpha the limbs are large but we normally need
@@ -178,6 +210,8 @@ _gcry_mpi_free( gcry_mpi_t a )
{
if (!a )
return;
+ if ((a->flags & 32))
+ return; /* Never release a constant. */
if ((a->flags & 4))
gcry_free( a->d );
else
@@ -195,7 +229,7 @@ _gcry_mpi_free( gcry_mpi_t a )
void
_gcry_mpi_immutable_failed (void)
{
- log_info ("Warning: trying to change immutable MPI\n");
+ log_info ("Warning: trying to change an immutable MPI\n");
}
@@ -226,6 +260,12 @@ gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
if (!a)
a = mpi_alloc(0);
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return a;
+ }
+
if( a->flags & 4 )
gcry_free( a->d );
else
@@ -266,6 +306,7 @@ gcry_mpi_copy( gcry_mpi_t a )
: gcry_xmalloc( (a->sign+7)/8 );
memcpy( p, a->d, (a->sign+7)/8 );
b = gcry_mpi_set_opaque( NULL, p, a->sign );
+ b->flags &= ~(16|32); /* Reset the immutable and constant flags. */
}
else if( a ) {
b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
@@ -273,6 +314,7 @@ gcry_mpi_copy( gcry_mpi_t a )
b->nlimbs = a->nlimbs;
b->sign = a->sign;
b->flags = a->flags;
+ b->flags &= ~(16|32); /* Reset the immutable and constant flags. */
for(i=0; i < b->nlimbs; i++ )
b->d[i] = a->d[i];
}
@@ -478,24 +520,30 @@ gcry_mpi_randomize( gcry_mpi_t w,
void
-gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+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_IMMUTABLE: a->flags |= 16; break;
- case GCRYMPI_FLAG_OPAQUE:
- default: log_bug("invalid flag value\n");
+ switch (flag)
+ {
+ case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
+ case GCRYMPI_FLAG_CONST: a->flags |= (16|32); break;
+ case GCRYMPI_FLAG_IMMUTABLE: a->flags |= 16; break;
+ case GCRYMPI_FLAG_OPAQUE:
+ default: log_bug("invalid flag value\n");
}
}
void
-gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
{
(void)a; /* Not yet used. */
switch (flag)
{
- case GCRYMPI_FLAG_IMMUTABLE: a->flags &= ~16; break;
+ case GCRYMPI_FLAG_IMMUTABLE:
+ if (!(a->flags & 32))
+ a->flags &= ~16;
+ break;
+ case GCRYMPI_FLAG_CONST:
case GCRYMPI_FLAG_SECURE:
case GCRYMPI_FLAG_OPAQUE:
default: log_bug("invalid flag value\n");
@@ -503,15 +551,30 @@ gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
}
int
-gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
{
switch (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);
+ case GCRYMPI_FLAG_SECURE: return !!(a->flags & 1);
+ case GCRYMPI_FLAG_OPAQUE: return !!(a->flags & 4);
+ case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16);
+ case GCRYMPI_FLAG_CONST: return !!(a->flags & 32);
default: log_bug("invalid flag value\n");
}
/*NOTREACHED*/
return 0;
}
+
+
+/* Return a constant MPI descripbed by NO which is one of the
+ MPI_C_xxx macros. There is no need to copy this returned value; it
+ may be used directly. */
+gcry_mpi_t
+_gcry_mpi_const (enum gcry_mpi_constants no)
+{
+ if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
+ log_bug("invalid mpi_const selector %d\n", no);
+ if (!constants[no])
+ log_bug("MPI subsystem not initialized\n");
+ return constants[no];
+}