We currently use an old version of libgcrypt which results in us having fewer ciphers and missing on many other improvements. Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
155 lines
4.4 KiB
C
155 lines
4.4 KiB
C
/* 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
|
|
{
|
|
struct gcry_context *next;
|
|
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
|
|
function 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 next)
|
|
{
|
|
gcry_ctx_t ctx;
|
|
|
|
switch (type)
|
|
{
|
|
case CONTEXT_TYPE_EC:
|
|
case CONTEXT_TYPE_SINGLE_DATA:
|
|
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 = xtrycalloc (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;
|
|
ctx->next = next;
|
|
|
|
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.
|
|
Special usage: using TYPE with 0, which returns CTX->NEXT.
|
|
*/
|
|
void *
|
|
_gcry_ctx_get_pointer (gcry_ctx_t ctx, int type)
|
|
{
|
|
if (!ctx || memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
|
|
log_fatal ("bad pointer %p passed to _gcry_ctx_get_pointer\n", ctx);
|
|
|
|
if (type == 0)
|
|
return ctx->next;
|
|
|
|
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;
|
|
}
|
|
|
|
/* 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. In contrast to
|
|
_gcry_ctx_get_pointer, this function returns NULL if no context for
|
|
the given type was found. If CTX is NULL the function does not
|
|
abort but returns NULL. */
|
|
void *
|
|
_gcry_ctx_find_pointer (gcry_ctx_t ctx, int type)
|
|
{
|
|
if (!ctx)
|
|
return NULL;
|
|
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)
|
|
return NULL;
|
|
return &ctx->u;
|
|
}
|
|
|
|
|
|
/* Release the generic context CTX. */
|
|
void
|
|
_gcry_ctx_release (gcry_ctx_t ctx)
|
|
{
|
|
gcry_ctx_t ctx_next;
|
|
|
|
again:
|
|
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:
|
|
case CONTEXT_TYPE_SINGLE_DATA:
|
|
break;
|
|
default:
|
|
log_fatal ("bad context type %d detected in gcry_ctx_relase\n",
|
|
ctx->type);
|
|
break;
|
|
}
|
|
if (ctx->deinit)
|
|
ctx->deinit (&ctx->u);
|
|
ctx_next = ctx->next;
|
|
xfree (ctx);
|
|
ctx = ctx_next;
|
|
goto again;
|
|
}
|