summaryrefslogtreecommitdiff
path: root/src/context.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-03-08 22:10:23 +0100
committerWerner Koch <wk@gnupg.org>2013-03-08 22:13:52 +0100
commit8ac9e756d3ca545a9b97e61ad3d42fc2e877d788 (patch)
tree9c371da68f09dca2379381529f9d7810957260b2 /src/context.c
parent7cce620acddac2df024ca421ed3abc32a88f3738 (diff)
downloadlibgcrypt-8ac9e756d3ca545a9b97e61ad3d42fc2e877d788.tar.gz
mpi: Add an API for EC math.
* src/context.c, src/context.h: New. * src/Makefile.am (libgcrypt_la_SOURCES): Add new files. * src/gcrypt.h.in (struct gcry_context, gcry_ctx_t): New types. (gcry_ctx_release): New prototype. (gcry_mpi_ec_p_new, gcry_mpi_ec_get_affine, gcry_mpi_ec_dup) (gcry_mpi_ec_add, gcry_mpi_ec_mul): New prototypes. * mpi/ec.c: Include errno.h and context.h. (_gcry_mpi_ec_init): Rename to .. (ec_p_init): this, make static, remove allocation and add arg CTX. (_gcry_mpi_ec_p_internal_new): New; to replace _gcry_mpi_ec_init. Change all callers to use this func. (_gcry_mpi_ec_free): Factor code out to .. (ec_deinit): New func. (gcry_mpi_ec_p_new): New. * src/visibility.c: Include context.h and mpi.h. (gcry_mpi_ec_p_new, gcry_mpi_ec_get_affine, gcry_mpi_ec_dup) (gcry_mpi_ec_add, gcry_mpi_ec_mul) (gcry_ctx_release): New wrapper functions. * src/visibility.h: Mark new wrapper functions visible. * src/libgcrypt.def, src/libgcrypt.vers: Add new symbols. * tests/t-mpi-point.c (print_mpi, hex2mpi, cmp_mpihex): New. (context_alloc): New. (make_point, basic_ec_math): New. -- This part finishes the basic API to do EC math. It provides a wrapper around all internal functions. tests/t-mpi-point.c may be useful as sample code. Eventually we will add function to retrieve curve parameters etc.
Diffstat (limited to 'src/context.c')
-rw-r--r--src/context.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/context.c b/src/context.c
new file mode 100644
index 00000000..ae991c52
--- /dev/null
+++ b/src/context.c
@@ -0,0 +1,118 @@
+/* context.c - Context management
+ * Copyright (C) 2013 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "context.h"
+
+#define CTX_MAGIC "cTx"
+#define CTX_MAGIC_LEN 3
+
+
+/* The definition of the generic context object. The public typedef
+ gcry_ctx_t is used to access it. */
+struct gcry_context
+{
+ char magic[CTX_MAGIC_LEN]; /* Magic value to cross check that this
+ is really a context object. */
+ char type; /* The type of the context (CONTEXT_TYPE_foo). */
+
+ void (*deinit)(void*); /* Function used to free the private part. */
+ PROPERLY_ALIGNED_TYPE u;
+};
+
+
+/* Allocate a fresh generic context of contect TYPE and allocate
+ LENGTH extra bytes for private use of the type handler. DEINIT is a
+ fucntion used called to deinitialize the private part; it may be
+ NULL if de-initialization is not required. Returns NULL and sets
+ ERRNO if memory allocation failed. */
+gcry_ctx_t
+_gcry_ctx_alloc (int type, size_t length, void (*deinit)(void*))
+{
+ gcry_ctx_t ctx;
+
+ switch (type)
+ {
+ case CONTEXT_TYPE_EC:
+ break;
+ default:
+ log_bug ("bad context type %d given to _gcry_ctx_alloc\n", type);
+ break;
+ }
+
+ if (length < sizeof (PROPERLY_ALIGNED_TYPE))
+ length = sizeof (PROPERLY_ALIGNED_TYPE);
+
+ ctx = gcry_calloc (1, sizeof *ctx - sizeof (PROPERLY_ALIGNED_TYPE) + length);
+ if (!ctx)
+ return NULL;
+ memcpy (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN);
+ ctx->type = type;
+ ctx->deinit = deinit;
+
+ return ctx;
+}
+
+
+/* Return a pointer to the private part of the context CTX. TYPE is
+ the requested context type. Using an explicit type allows to cross
+ check the type and eventually allows to store several private
+ contexts in one context object. The function does not return an
+ error but aborts if the provided CTX is not valid. */
+void *
+_gcry_ctx_get_pointer (gcry_ctx_t ctx, int type)
+{
+ if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
+ log_fatal ("bad pointer %p passed to _gcry_ctx_get_pointer\n", ctx);
+ if (ctx->type != type)
+ log_fatal ("wrong context type %d request for context %p of type %d\n",
+ type, ctx, ctx->type);
+ return &ctx->u;
+}
+
+
+/* Release the generic context CTX. */
+void
+gcry_ctx_release (gcry_ctx_t ctx)
+{
+ if (!ctx)
+ return;
+ if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
+ log_fatal ("bad pointer %p passed to gcry_ctx_relase\n", ctx);
+ switch (ctx->type)
+ {
+ case CONTEXT_TYPE_EC:
+ break;
+ default:
+ log_fatal ("bad context type %d detected in gcry_ctx_relase\n",
+ ctx->type);
+ break;
+ }
+ if (ctx->deinit)
+ ctx->deinit (&ctx->u);
+ gcry_free (ctx);
+}