/* crypto/ec/ec_lib.c */
/* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include <string.h>
#include <openssl/err.h>
+#include <openssl/opensslv.h>
#include "ec_lcl.h"
+static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
+
/* functions for EC_GROUP objects */
ret->extra_data_dup_func = 0;
ret->extra_data_free_func = 0;
ret->extra_data_clear_free_func = 0;
-
+
+ ret->generator = NULL;
+ BN_init(&ret->order);
+ BN_init(&ret->cofactor);
+
+ ret->nid = 0;
+
if (!meth->group_init(ret))
{
OPENSSL_free(ret);
}
-int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
- {
- if (group->meth->group_set_curve_GFp == 0)
- {
- ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- return group->meth->group_set_curve_GFp(group, p, a, b, ctx);
- }
-
-
void EC_GROUP_free(EC_GROUP *group)
{
if (group->meth->group_finish != 0)
EC_GROUP_free_extra_data(group);
+ if (group->generator != NULL)
+ EC_POINT_free(group->generator);
+ BN_free(&group->order);
+ BN_free(&group->cofactor);
+
OPENSSL_free(group);
}
EC_GROUP_clear_free_extra_data(group);
+ if (group->generator != NULL)
+ EC_POINT_clear_free(group->generator);
+ BN_clear_free(&group->order);
+ BN_clear_free(&group->cofactor);
+
memset(group, 0, sizeof *group);
OPENSSL_free(group);
}
dest->extra_data_clear_free_func = src->extra_data_clear_free_func;
}
+ if (src->generator != NULL)
+ {
+ if (dest->generator == NULL)
+ {
+ dest->generator = EC_POINT_new(dest);
+ if (dest->generator == NULL) return 0;
+ }
+ if (!EC_POINT_copy(dest->generator, src->generator)) return 0;
+ }
+ else
+ {
+ /* src->generator == NULL */
+ if (dest->generator != NULL)
+ {
+ EC_POINT_clear_free(dest->generator);
+ dest->generator = NULL;
+ }
+ }
+
+ if (!BN_copy(&dest->order, &src->order)) return 0;
+ if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0;
+
+ dest->nid = src->nid;
+
return dest->meth->group_copy(dest, src);
}
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
+ {
+ return group->meth;
+ }
+
+
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
{
- if (group->meth->group_set_generator == 0)
+ if (generator == NULL)
{
- ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
+ return 0 ;
+ }
+
+ if (group->generator == NULL)
+ {
+ group->generator = EC_POINT_new(group);
+ if (group->generator == NULL) return 0;
+ }
+ if (!EC_POINT_copy(group->generator, generator)) return 0;
+
+ if (order != NULL)
+ { if (!BN_copy(&group->order, order)) return 0; }
+ else
+ { if (!BN_zero(&group->order)) return 0; }
+
+ if (cofactor != NULL)
+ { if (!BN_copy(&group->cofactor, cofactor)) return 0; }
+ else
+ { if (!BN_zero(&group->cofactor)) return 0; }
+
+ return 1;
+ }
+
+
+EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
+ {
+ return group->generator;
+ }
+
+
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
+ {
+ if (!BN_copy(order, &group->order))
+ return 0;
+
+ return !BN_is_zero(order);
+ }
+
+
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
+ {
+ if (!BN_copy(cofactor, &group->cofactor))
+ return 0;
+
+ return !BN_is_zero(&group->cofactor);
+ }
+
+
+void EC_GROUP_set_nid(EC_GROUP *group, int nid)
+ {
+ group->nid = nid;
+ }
+
+
+int EC_GROUP_get_nid(const EC_GROUP *group)
+ {
+ return group->nid;
+ }
+
+
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+ {
+ if (group->meth->group_set_curve_GFp == 0)
+ {
+ ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->group_set_curve_GFp(group, p, a, b, ctx);
+ }
+
+
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+ {
+ if (group->meth->group_get_curve_GFp == 0)
+ {
+ ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
- return group->meth->group_set_generator(group, generator, order, cofactor);
+ return group->meth->group_get_curve_GFp(group, p, a, b, ctx);
}
-/* TODO: 'set' and 'get' functions for EC_GROUPs */
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+ {
+ if (group->meth->group_check_discriminant == 0)
+ {
+ ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->group_check_discriminant(group, ctx);
+ }
/* this has 'package' visibility */
/* this has 'package' visibility */
-void *EC_GROUP_get_extra_data(EC_GROUP *group, void *(*extra_data_dup_func)(void *),
+void *EC_GROUP_get_extra_data(const 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)
}
-
/* functions for EC_POINT objects */
EC_POINT *EC_POINT_new(const EC_GROUP *group)
ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
+ if (dest == src)
+ return 1;
return dest->meth->point_copy(dest, src);
}
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
+ {
+ return point->meth;
+ }
+
+
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
{
if (group->meth->point_set_to_infinity == 0)
}
return group->meth->make_affine(group, point, ctx);
}
+
+
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
+ {
+ size_t i;
+
+ if (group->meth->points_make_affine == 0)
+ {
+ ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ for (i = 0; i < num; i++)
+ {
+ if (group->meth != points[i]->meth)
+ {
+ ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ }
+ return group->meth->points_make_affine(group, num, points, ctx);
+ }