summaryrefslogtreecommitdiff
path: root/mpi/mpiutil.c
diff options
context:
space:
mode:
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];
+}