Commit df9cc153 authored by Bodo Möller's avatar Bodo Möller
Browse files

extra_data 'mixin'.

(This will be used for Lim/Lee precomputation data.)
parent c4b36ff4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -153,8 +153,10 @@ int EC_POINT_make_affine(const EC_GROUP *, const EC_POINT *, BN_CTX *);
#define EC_F_EC_GROUP_CLEAR_FREE			 103
#define EC_F_EC_GROUP_COPY				 102
#define EC_F_EC_GROUP_FREE				 104
#define EC_F_EC_GROUP_GET_EXTRA_DATA			 115
#define EC_F_EC_GROUP_NEW				 100
#define EC_F_EC_GROUP_SET_CURVE_GFP			 101
#define EC_F_EC_GROUP_SET_EXTRA_DATA			 116
#define EC_F_EC_GROUP_SET_GENERATOR			 106
#define EC_F_EC_POINT_ADD				 107
#define EC_F_EC_POINT_COPY				 108
@@ -168,6 +170,8 @@ int EC_POINT_make_affine(const EC_GROUP *, const EC_POINT *, BN_CTX *);

/* Reason codes. */
#define EC_R_INCOMPATIBLE_OBJECTS			 100
#define EC_R_NO_SUCH_EXTRA_DATA				 101
#define EC_R_SLOT_FULL					 102

#ifdef  __cplusplus
}
+4 −0
Original line number Diff line number Diff line
@@ -69,8 +69,10 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_PACK(0,EC_F_EC_GROUP_CLEAR_FREE,0),	"EC_GROUP_clear_free"},
{ERR_PACK(0,EC_F_EC_GROUP_COPY,0),	"EC_GROUP_copy"},
{ERR_PACK(0,EC_F_EC_GROUP_FREE,0),	"EC_GROUP_free"},
{ERR_PACK(0,EC_F_EC_GROUP_GET_EXTRA_DATA,0),	"EC_GROUP_GET_EXTRA_DATA"},
{ERR_PACK(0,EC_F_EC_GROUP_NEW,0),	"EC_GROUP_new"},
{ERR_PACK(0,EC_F_EC_GROUP_SET_CURVE_GFP,0),	"EC_GROUP_set_curve_GFp"},
{ERR_PACK(0,EC_F_EC_GROUP_SET_EXTRA_DATA,0),	"EC_GROUP_SET_EXTRA_DATA"},
{ERR_PACK(0,EC_F_EC_GROUP_SET_GENERATOR,0),	"EC_GROUP_set_generator"},
{ERR_PACK(0,EC_F_EC_POINT_ADD,0),	"EC_POINT_add"},
{ERR_PACK(0,EC_F_EC_POINT_COPY,0),	"EC_POINT_copy"},
@@ -87,6 +89,8 @@ static ERR_STRING_DATA EC_str_functs[]=
static ERR_STRING_DATA EC_str_reasons[]=
	{
{EC_R_INCOMPATIBLE_OBJECTS               ,"incompatible objects"},
{EC_R_NO_SUCH_EXTRA_DATA                 ,"no such extra data"},
{EC_R_SLOT_FULL                          ,"slot full"},
{0,NULL}
	};

+23 −2
Original line number Diff line number Diff line
@@ -119,8 +119,13 @@ struct ec_method_st {
struct ec_group_st {
	const EC_METHOD *meth;

	/* All members except 'meth' are handled by the method functions,
	 * even if they appear generic */
	void *extra_data;
	void *(*extra_data_dup_func)(void *);
	void (*extra_data_free_func)(void *);
	void (*extra_data_clear_free_func)(void *);

	/* All members except 'meth' and 'extra_data...' are handled by
	 * the method functions, even if they appear generic */
	
	BIGNUM field; /* Field specification.
	               * For curves over GF(p), this is the modulus. */
@@ -142,6 +147,22 @@ struct ec_group_st {
} /* EC_GROUP */;


/* Basically a 'mixin' for extra data, but available for EC_GROUPs only
 * (with visibility limited to 'package' level for now).
 * We use the function pointers as index for retrieval; this obviates
 * global ex_data-style index tables.
 * (Currently, we have one slot only, but is is possible to extend this
 * if necessary.) */

int EC_GROUP_set_extra_data(EC_GROUP *, void *extra_data, void *(*extra_data_dup_func)(void *),
	void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *));
void *EC_GROUP_get_extra_data(EC_GROUP *, void *(*extra_data_dup_func)(void *),
	void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *));
void EC_GROUP_free_extra_data(EC_GROUP *);
void EC_GROUP_clear_free_extra_data(EC_GROUP *);



struct ec_point_st {
	const EC_METHOD *meth;

+89 −0
Original line number Diff line number Diff line
@@ -86,6 +86,11 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)

	ret->meth = meth;

	ret->extra_data = NULL;
	ret->extra_data_dup_func = 0;
	ret->extra_data_free_func = 0;
	ret->extra_data_clear_free_func = 0;
	
	if (!meth->group_init(ret))
		{
		OPENSSL_free(ret);
@@ -112,6 +117,9 @@ void EC_GROUP_free(EC_GROUP *group)
	{
	if (group->meth->group_finish != 0)
		group->meth->group_finish(group);

	EC_GROUP_free_extra_data(group);

	OPENSSL_free(group);
	}
 
@@ -122,6 +130,9 @@ void EC_GROUP_clear_free(EC_GROUP *group)
		group->meth->group_clear_finish(group);
	else if (group->meth != NULL && group->meth->group_finish != 0)
		group->meth->group_finish(group);

	EC_GROUP_clear_free_extra_data(group);

	memset(group, 0, sizeof *group);
	OPENSSL_free(group);
	}
@@ -140,6 +151,21 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
		return 0;
		}
	
	EC_GROUP_clear_free_extra_data(dest);
	if (src->extra_data_dup_func)
		{
		if (src->extra_data != NULL)
			{
			dest->extra_data = src->extra_data_dup_func(src->extra_data);
			if (dest->extra_data == NULL)
				return 0;
			}

		dest->extra_data_dup_func = src->extra_data_dup_func;
		dest->extra_data_free_func = src->extra_data_free_func;
		dest->extra_data_clear_free_func = src->extra_data_clear_free_func;
		}

	return dest->meth->group_copy(dest, src);
	}

@@ -158,6 +184,69 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIG
/* TODO: 'get' functions for EC_GROUPs */


/* this has 'package' visibility */
int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *),
	void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
	{
	if ((group->extra_data != NULL)
		|| (group->extra_data_dup_func != 0)
		|| (group->extra_data_free_func != 0)
		|| (group->extra_data_clear_free_func != 0))
		{
		ECerr(EC_F_EC_GROUP_SET_EXTRA_DATA, EC_R_SLOT_FULL);
		return 0;
		}

	group->extra_data = extra_data;
	group->extra_data_dup_func = extra_data_dup_func;
	group->extra_data_free_func = extra_data_free_func;
	group->extra_data_clear_free_func = extra_data_clear_free_func;
	return 1;
	}


/* this has 'package' visibility */
void *EC_GROUP_get_extra_data(EC_GROUP *group, void *(*extra_data_dup_func)(void *),
	void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
	{
	if ((group->extra_data_dup_func != extra_data_dup_func)
		|| (group->extra_data_free_func != extra_data_free_func)
		|| (group->extra_data_clear_free_func != extra_data_clear_free_func))
		{
		ECerr(EC_F_EC_GROUP_GET_EXTRA_DATA, EC_R_NO_SUCH_EXTRA_DATA);
		return NULL;
		}

	return group->extra_data;
	}


/* this has 'package' visibility */
void EC_GROUP_free_extra_data(EC_GROUP *group)
	{
	if (group->extra_data_free_func)
		group->extra_data_free_func(group->extra_data);
	group->extra_data = NULL;
	group->extra_data_dup_func = 0;
	group->extra_data_free_func = 0;
	group->extra_data_clear_free_func = 0;
	}


/* this has 'package' visibility */
void EC_GROUP_clear_free_extra_data(EC_GROUP *group)
	{
	if (group->extra_data_clear_free_func)
		group->extra_data_clear_free_func(group->extra_data);
	else if (group->extra_data_free_func)
		group->extra_data_free_func(group->extra_data);
	group->extra_data = NULL;
	group->extra_data_dup_func = 0;
	group->extra_data_free_func = 0;
	group->extra_data_clear_free_func = 0;
	}



/* functions for EC_POINT objects */