Line data Source code
1 : /* context.c - Context management
2 : * Copyright (C) 2013 g10 Code GmbH
3 : *
4 : * This file is part of Libgcrypt.
5 : *
6 : * Libgcrypt is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * Libgcrypt is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <config.h>
21 : #include <stdio.h>
22 : #include <stdlib.h>
23 : #include <string.h>
24 : #include <stdarg.h>
25 : #include <unistd.h>
26 :
27 : #include "g10lib.h"
28 : #include "mpi.h"
29 : #include "context.h"
30 :
31 : #define CTX_MAGIC "cTx"
32 : #define CTX_MAGIC_LEN 3
33 :
34 :
35 : /* The definition of the generic context object. The public typedef
36 : gcry_ctx_t is used to access it. */
37 : struct gcry_context
38 : {
39 : char magic[CTX_MAGIC_LEN]; /* Magic value to cross check that this
40 : is really a context object. */
41 : char type; /* The type of the context (CONTEXT_TYPE_foo). */
42 :
43 : void (*deinit)(void*); /* Function used to free the private part. */
44 : PROPERLY_ALIGNED_TYPE u;
45 : };
46 :
47 :
48 : /* Allocate a fresh generic context of contect TYPE and allocate
49 : LENGTH extra bytes for private use of the type handler. DEINIT is a
50 : fucntion used called to deinitialize the private part; it may be
51 : NULL if de-initialization is not required. Returns NULL and sets
52 : ERRNO if memory allocation failed. */
53 : gcry_ctx_t
54 12 : _gcry_ctx_alloc (int type, size_t length, void (*deinit)(void*))
55 : {
56 : gcry_ctx_t ctx;
57 :
58 12 : switch (type)
59 : {
60 : case CONTEXT_TYPE_EC:
61 12 : break;
62 : default:
63 0 : log_bug ("bad context type %d given to _gcry_ctx_alloc\n", type);
64 : break;
65 : }
66 :
67 12 : if (length < sizeof (PROPERLY_ALIGNED_TYPE))
68 0 : length = sizeof (PROPERLY_ALIGNED_TYPE);
69 :
70 12 : ctx = xtrycalloc (1, sizeof *ctx - sizeof (PROPERLY_ALIGNED_TYPE) + length);
71 12 : if (!ctx)
72 0 : return NULL;
73 12 : memcpy (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN);
74 12 : ctx->type = type;
75 12 : ctx->deinit = deinit;
76 :
77 12 : return ctx;
78 : }
79 :
80 :
81 : /* Return a pointer to the private part of the context CTX. TYPE is
82 : the requested context type. Using an explicit type allows to cross
83 : check the type and eventually allows to store several private
84 : contexts in one context object. The function does not return an
85 : error but aborts if the provided CTX is not valid. */
86 : void *
87 109 : _gcry_ctx_get_pointer (gcry_ctx_t ctx, int type)
88 : {
89 109 : if (!ctx || memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
90 0 : log_fatal ("bad pointer %p passed to _gcry_ctx_get_pointer\n", ctx);
91 109 : if (ctx->type != type)
92 0 : log_fatal ("wrong context type %d request for context %p of type %d\n",
93 0 : type, ctx, ctx->type);
94 109 : return &ctx->u;
95 : }
96 :
97 : /* Return a pointer to the private part of the context CTX. TYPE is
98 : the requested context type. Using an explicit type allows to cross
99 : check the type and eventually allows to store several private
100 : contexts in one context object. In contrast to
101 : _gcry_ctx_get_pointer, this function returns NULL if no context for
102 : the given type was found. If CTX is NULL the function does not
103 : abort but returns NULL. */
104 : void *
105 11 : _gcry_ctx_find_pointer (gcry_ctx_t ctx, int type)
106 : {
107 11 : if (!ctx)
108 0 : return NULL;
109 11 : if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
110 0 : log_fatal ("bad pointer %p passed to _gcry_ctx_get_pointer\n", ctx);
111 11 : if (ctx->type != type)
112 0 : return NULL;
113 11 : return &ctx->u;
114 : }
115 :
116 :
117 : /* Release the generic context CTX. */
118 : void
119 27 : _gcry_ctx_release (gcry_ctx_t ctx)
120 : {
121 27 : if (!ctx)
122 42 : return;
123 12 : if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
124 0 : log_fatal ("bad pointer %p passed to gcry_ctx_relase\n", ctx);
125 12 : switch (ctx->type)
126 : {
127 : case CONTEXT_TYPE_EC:
128 12 : break;
129 : default:
130 0 : log_fatal ("bad context type %d detected in gcry_ctx_relase\n",
131 0 : ctx->type);
132 : break;
133 : }
134 12 : if (ctx->deinit)
135 12 : ctx->deinit (&ctx->u);
136 12 : xfree (ctx);
137 : }
|