summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine')
-rw-r--r--src/lib/libcrypto/engine/eng_all.c31
-rw-r--r--src/lib/libcrypto/engine/eng_cnf.c7
-rw-r--r--src/lib/libcrypto/engine/eng_ctrl.c12
-rw-r--r--src/lib/libcrypto/engine/eng_dyn.c108
-rw-r--r--src/lib/libcrypto/engine/eng_err.c16
-rw-r--r--src/lib/libcrypto/engine/eng_fat.c26
-rw-r--r--src/lib/libcrypto/engine/eng_init.c5
-rw-r--r--src/lib/libcrypto/engine/eng_int.h9
-rw-r--r--src/lib/libcrypto/engine/eng_lib.c18
-rw-r--r--src/lib/libcrypto/engine/eng_list.c43
-rw-r--r--src/lib/libcrypto/engine/eng_openssl.c25
-rw-r--r--src/lib/libcrypto/engine/eng_padlock.c1219
-rw-r--r--src/lib/libcrypto/engine/eng_pkey.c3
-rw-r--r--src/lib/libcrypto/engine/eng_table.c94
-rw-r--r--src/lib/libcrypto/engine/engine.h158
-rw-r--r--src/lib/libcrypto/engine/tb_cipher.c2
-rw-r--r--src/lib/libcrypto/engine/tb_dh.c2
-rw-r--r--src/lib/libcrypto/engine/tb_digest.c2
-rw-r--r--src/lib/libcrypto/engine/tb_dsa.c2
-rw-r--r--src/lib/libcrypto/engine/tb_ecdh.c133
-rw-r--r--src/lib/libcrypto/engine/tb_ecdsa.c118
-rw-r--r--src/lib/libcrypto/engine/tb_rand.c2
-rw-r--r--src/lib/libcrypto/engine/tb_rsa.c2
-rw-r--r--src/lib/libcrypto/engine/tb_store.c123
24 files changed, 1966 insertions, 194 deletions
diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c
index 0f6992a40d..8599046717 100644
--- a/src/lib/libcrypto/engine/eng_all.c
+++ b/src/lib/libcrypto/engine/eng_all.c
@@ -56,8 +56,7 @@
56 * 56 *
57 */ 57 */
58 58
59#include <openssl/err.h> 59#include "cryptlib.h"
60#include <openssl/engine.h>
61#include "eng_int.h" 60#include "eng_int.h"
62 61
63void ENGINE_load_builtin_engines(void) 62void ENGINE_load_builtin_engines(void)
@@ -69,32 +68,42 @@ void ENGINE_load_builtin_engines(void)
69#if 0 68#if 0
70 ENGINE_load_openssl(); 69 ENGINE_load_openssl();
71#endif 70#endif
71#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
72 ENGINE_load_padlock();
73#endif
72 ENGINE_load_dynamic(); 74 ENGINE_load_dynamic();
75#ifndef OPENSSL_NO_STATIC_ENGINE
73#ifndef OPENSSL_NO_HW 76#ifndef OPENSSL_NO_HW
77#ifndef OPENSSL_NO_HW_4758_CCA
78 ENGINE_load_4758cca();
79#endif
80#ifndef OPENSSL_NO_HW_AEP
81 ENGINE_load_aep();
82#endif
83#ifndef OPENSSL_NO_HW_ATALLA
84 ENGINE_load_atalla();
85#endif
74#ifndef OPENSSL_NO_HW_CSWIFT 86#ifndef OPENSSL_NO_HW_CSWIFT
75 ENGINE_load_cswift(); 87 ENGINE_load_cswift();
76#endif 88#endif
77#ifndef OPENSSL_NO_HW_NCIPHER 89#ifndef OPENSSL_NO_HW_NCIPHER
78 ENGINE_load_chil(); 90 ENGINE_load_chil();
79#endif 91#endif
80#ifndef OPENSSL_NO_HW_ATALLA
81 ENGINE_load_atalla();
82#endif
83#ifndef OPENSSL_NO_HW_NURON 92#ifndef OPENSSL_NO_HW_NURON
84 ENGINE_load_nuron(); 93 ENGINE_load_nuron();
85#endif 94#endif
95#ifndef OPENSSL_NO_HW_SUREWARE
96 ENGINE_load_sureware();
97#endif
86#ifndef OPENSSL_NO_HW_UBSEC 98#ifndef OPENSSL_NO_HW_UBSEC
87 ENGINE_load_ubsec(); 99 ENGINE_load_ubsec();
88#endif 100#endif
89#ifndef OPENSSL_NO_HW_AEP
90 ENGINE_load_aep();
91#endif 101#endif
92#ifndef OPENSSL_NO_HW_SUREWARE 102#if !defined(OPENSSL_NO_GMP) && !defined(OPENSSL_NO_HW_GMP)
93 ENGINE_load_sureware(); 103 ENGINE_load_gmp();
94#endif 104#endif
95#ifndef OPENSSL_NO_HW_4758_CCA
96 ENGINE_load_4758cca();
97#endif 105#endif
106#ifndef OPENSSL_NO_HW
98#if defined(__OpenBSD__) || defined(__FreeBSD__) 107#if defined(__OpenBSD__) || defined(__FreeBSD__)
99 ENGINE_load_cryptodev(); 108 ENGINE_load_cryptodev();
100#endif 109#endif
diff --git a/src/lib/libcrypto/engine/eng_cnf.c b/src/lib/libcrypto/engine/eng_cnf.c
index 4225760af1..a97e01e619 100644
--- a/src/lib/libcrypto/engine/eng_cnf.c
+++ b/src/lib/libcrypto/engine/eng_cnf.c
@@ -56,11 +56,8 @@
56 * 56 *
57 */ 57 */
58 58
59#include <stdio.h> 59#include "eng_int.h"
60#include <openssl/crypto.h>
61#include "cryptlib.h"
62#include <openssl/conf.h> 60#include <openssl/conf.h>
63#include <openssl/engine.h>
64 61
65/* #define ENGINE_CONF_DEBUG */ 62/* #define ENGINE_CONF_DEBUG */
66 63
@@ -210,7 +207,7 @@ static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
210 207
211 if (!elist) 208 if (!elist)
212 { 209 {
213 ENGINEerr(ENGINE_F_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR); 210 ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
214 return 0; 211 return 0;
215 } 212 }
216 213
diff --git a/src/lib/libcrypto/engine/eng_ctrl.c b/src/lib/libcrypto/engine/eng_ctrl.c
index 412c73fb0f..95b6b455aa 100644
--- a/src/lib/libcrypto/engine/eng_ctrl.c
+++ b/src/lib/libcrypto/engine/eng_ctrl.c
@@ -53,10 +53,7 @@
53 * 53 *
54 */ 54 */
55 55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h" 56#include "eng_int.h"
59#include <openssl/engine.h>
60 57
61/* When querying a ENGINE-specific control command's 'description', this string 58/* When querying a ENGINE-specific control command's 'description', this string
62 * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */ 59 * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
@@ -103,7 +100,8 @@ static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
103 return -1; 100 return -1;
104 } 101 }
105 102
106static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)()) 103static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
104 void (*f)(void))
107 { 105 {
108 int idx; 106 int idx;
109 char *s = (char *)p; 107 char *s = (char *)p;
@@ -181,7 +179,7 @@ static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)())
181 return -1; 179 return -1;
182 } 180 }
183 181
184int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) 182int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
185 { 183 {
186 int ctrl_exists, ref_exists; 184 int ctrl_exists, ref_exists;
187 if(e == NULL) 185 if(e == NULL)
@@ -251,13 +249,13 @@ int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
251 } 249 }
252 250
253int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, 251int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
254 long i, void *p, void (*f)(), int cmd_optional) 252 long i, void *p, void (*f)(void), int cmd_optional)
255 { 253 {
256 int num; 254 int num;
257 255
258 if((e == NULL) || (cmd_name == NULL)) 256 if((e == NULL) || (cmd_name == NULL))
259 { 257 {
260 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, 258 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
261 ERR_R_PASSED_NULL_PARAMETER); 259 ERR_R_PASSED_NULL_PARAMETER);
262 return 0; 260 return 0;
263 } 261 }
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c
index 4139a16e76..acb30c34d8 100644
--- a/src/lib/libcrypto/engine/eng_dyn.c
+++ b/src/lib/libcrypto/engine/eng_dyn.c
@@ -57,11 +57,7 @@
57 */ 57 */
58 58
59 59
60#include <stdio.h>
61#include <openssl/crypto.h>
62#include "cryptlib.h"
63#include "eng_int.h" 60#include "eng_int.h"
64#include <openssl/engine.h>
65#include <openssl/dso.h> 61#include <openssl/dso.h>
66 62
67/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader 63/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
@@ -70,7 +66,7 @@
70/* Our ENGINE handlers */ 66/* Our ENGINE handlers */
71static int dynamic_init(ENGINE *e); 67static int dynamic_init(ENGINE *e);
72static int dynamic_finish(ENGINE *e); 68static int dynamic_finish(ENGINE *e);
73static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 69static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
74/* Predeclare our context type */ 70/* Predeclare our context type */
75typedef struct st_dynamic_data_ctx dynamic_data_ctx; 71typedef struct st_dynamic_data_ctx dynamic_data_ctx;
76/* The implementation for the important control command */ 72/* The implementation for the important control command */
@@ -80,7 +76,9 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
80#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1) 76#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1)
81#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2) 77#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2)
82#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3) 78#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3)
83#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 4) 79#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4)
80#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5)
81#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6)
84 82
85/* The constants used when creating the ENGINE */ 83/* The constants used when creating the ENGINE */
86static const char *engine_dynamic_id = "dynamic"; 84static const char *engine_dynamic_id = "dynamic";
@@ -102,6 +100,14 @@ static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
102 "LIST_ADD", 100 "LIST_ADD",
103 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", 101 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
104 ENGINE_CMD_FLAG_NUMERIC}, 102 ENGINE_CMD_FLAG_NUMERIC},
103 {DYNAMIC_CMD_DIR_LOAD,
104 "DIR_LOAD",
105 "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
106 ENGINE_CMD_FLAG_NUMERIC},
107 {DYNAMIC_CMD_DIR_ADD,
108 "DIR_ADD",
109 "Adds a directory from which ENGINEs can be loaded",
110 ENGINE_CMD_FLAG_STRING},
105 {DYNAMIC_CMD_LOAD, 111 {DYNAMIC_CMD_LOAD,
106 "LOAD", 112 "LOAD",
107 "Load up the ENGINE specified by other settings", 113 "Load up the ENGINE specified by other settings",
@@ -136,12 +142,18 @@ struct st_dynamic_data_ctx
136 const char *DYNAMIC_F1; 142 const char *DYNAMIC_F1;
137 /* The symbol name for the "initialise ENGINE structure" function */ 143 /* The symbol name for the "initialise ENGINE structure" function */
138 const char *DYNAMIC_F2; 144 const char *DYNAMIC_F2;
145 /* Whether to never use 'dirs', use 'dirs' as a fallback, or only use
146 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */
147 int dir_load;
148 /* A stack of directories from which ENGINEs could be loaded */
149 STACK *dirs;
139 }; 150 };
140 151
141/* This is the "ex_data" index we obtain and reserve for use with our context 152/* This is the "ex_data" index we obtain and reserve for use with our context
142 * structure. */ 153 * structure. */
143static int dynamic_ex_data_idx = -1; 154static int dynamic_ex_data_idx = -1;
144 155
156static void int_free_str(void *s) { OPENSSL_free(s); }
145/* Because our ex_data element may or may not get allocated depending on whether 157/* Because our ex_data element may or may not get allocated depending on whether
146 * a "first-use" occurs before the ENGINE is freed, we have a memory leak 158 * a "first-use" occurs before the ENGINE is freed, we have a memory leak
147 * problem to solve. We can't declare a "new" handler for the ex_data as we 159 * problem to solve. We can't declare a "new" handler for the ex_data as we
@@ -161,6 +173,8 @@ static void dynamic_data_ctx_free_func(void *parent, void *ptr,
161 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME); 173 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
162 if(ctx->engine_id) 174 if(ctx->engine_id)
163 OPENSSL_free((void*)ctx->engine_id); 175 OPENSSL_free((void*)ctx->engine_id);
176 if(ctx->dirs)
177 sk_pop_free(ctx->dirs, int_free_str);
164 OPENSSL_free(ctx); 178 OPENSSL_free(ctx);
165 } 179 }
166 } 180 }
@@ -175,7 +189,7 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
175 c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); 189 c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
176 if(!c) 190 if(!c)
177 { 191 {
178 ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); 192 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
179 return 0; 193 return 0;
180 } 194 }
181 memset(c, 0, sizeof(dynamic_data_ctx)); 195 memset(c, 0, sizeof(dynamic_data_ctx));
@@ -188,6 +202,14 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
188 c->list_add_value = 0; 202 c->list_add_value = 0;
189 c->DYNAMIC_F1 = "v_check"; 203 c->DYNAMIC_F1 = "v_check";
190 c->DYNAMIC_F2 = "bind_engine"; 204 c->DYNAMIC_F2 = "bind_engine";
205 c->dir_load = 1;
206 c->dirs = sk_new_null();
207 if(!c->dirs)
208 {
209 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
210 OPENSSL_free(c);
211 return 0;
212 }
191 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 213 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
192 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, 214 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
193 dynamic_ex_data_idx)) == NULL) 215 dynamic_ex_data_idx)) == NULL)
@@ -290,7 +312,7 @@ static int dynamic_finish(ENGINE *e)
290 return 0; 312 return 0;
291 } 313 }
292 314
293static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) 315static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
294 { 316 {
295 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); 317 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
296 int initialised; 318 int initialised;
@@ -346,6 +368,34 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
346 return 1; 368 return 1;
347 case DYNAMIC_CMD_LOAD: 369 case DYNAMIC_CMD_LOAD:
348 return dynamic_load(e, ctx); 370 return dynamic_load(e, ctx);
371 case DYNAMIC_CMD_DIR_LOAD:
372 if((i < 0) || (i > 2))
373 {
374 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
375 ENGINE_R_INVALID_ARGUMENT);
376 return 0;
377 }
378 ctx->dir_load = (int)i;
379 return 1;
380 case DYNAMIC_CMD_DIR_ADD:
381 /* a NULL 'p' or a string of zero-length is the same thing */
382 if(!p || (strlen((const char *)p) < 1))
383 {
384 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
385 ENGINE_R_INVALID_ARGUMENT);
386 return 0;
387 }
388 {
389 char *tmp_str = BUF_strdup(p);
390 if(!tmp_str)
391 {
392 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
393 ERR_R_MALLOC_FAILURE);
394 return 0;
395 }
396 sk_insert(ctx->dirs, tmp_str, -1);
397 }
398 return 1;
349 default: 399 default:
350 break; 400 break;
351 } 401 }
@@ -353,16 +403,53 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
353 return 0; 403 return 0;
354 } 404 }
355 405
406static int int_load(dynamic_data_ctx *ctx)
407 {
408 int num, loop;
409 /* Unless told not to, try a direct load */
410 if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
411 ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
412 return 1;
413 /* If we're not allowed to use 'dirs' or we have none, fail */
414 if(!ctx->dir_load || ((num = sk_num(ctx->dirs)) < 1))
415 return 0;
416 for(loop = 0; loop < num; loop++)
417 {
418 const char *s = sk_value(ctx->dirs, loop);
419 char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
420 if(!merge)
421 return 0;
422 if(DSO_load(ctx->dynamic_dso, merge, NULL, 0))
423 {
424 /* Found what we're looking for */
425 OPENSSL_free(merge);
426 return 1;
427 }
428 OPENSSL_free(merge);
429 }
430 return 0;
431 }
432
356static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) 433static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
357 { 434 {
358 ENGINE cpy; 435 ENGINE cpy;
359 dynamic_fns fns; 436 dynamic_fns fns;
360 437
361 if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL, 438 if(!ctx->dynamic_dso)
362 ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL)) 439 ctx->dynamic_dso = DSO_new();
440 if(!ctx->DYNAMIC_LIBNAME)
441 {
442 if(!ctx->engine_id)
443 return 0;
444 ctx->DYNAMIC_LIBNAME =
445 DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
446 }
447 if(!int_load(ctx))
363 { 448 {
364 ENGINEerr(ENGINE_F_DYNAMIC_LOAD, 449 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
365 ENGINE_R_DSO_NOT_FOUND); 450 ENGINE_R_DSO_NOT_FOUND);
451 DSO_free(ctx->dynamic_dso);
452 ctx->dynamic_dso = NULL;
366 return 0; 453 return 0;
367 } 454 }
368 /* We have to find a bind function otherwise it'll always end badly */ 455 /* We have to find a bind function otherwise it'll always end badly */
@@ -409,6 +496,7 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
409 * engine.h, much of this would be simplified if each area of code 496 * engine.h, much of this would be simplified if each area of code
410 * provided its own "summary" structure of all related callbacks. It 497 * provided its own "summary" structure of all related callbacks. It
411 * would also increase opaqueness. */ 498 * would also increase opaqueness. */
499 fns.static_state = ENGINE_get_static_state();
412 fns.err_fns = ERR_get_implementation(); 500 fns.err_fns = ERR_get_implementation();
413 fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); 501 fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
414 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, 502 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c
index fdc0e7be0f..369f2e22d3 100644
--- a/src/lib/libcrypto/engine/eng_err.c
+++ b/src/lib/libcrypto/engine/eng_err.c
@@ -73,6 +73,7 @@ static ERR_STRING_DATA ENGINE_str_functs[]=
73{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "DYNAMIC_CTRL"}, 73{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "DYNAMIC_CTRL"},
74{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "DYNAMIC_GET_DATA_CTX"}, 74{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "DYNAMIC_GET_DATA_CTX"},
75{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "DYNAMIC_LOAD"}, 75{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "DYNAMIC_LOAD"},
76{ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "DYNAMIC_SET_DATA_CTX"},
76{ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"}, 77{ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"},
77{ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"}, 78{ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"},
78{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"}, 79{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"},
@@ -80,7 +81,7 @@ static ERR_STRING_DATA ENGINE_str_functs[]=
80{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"}, 81{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"},
81{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"}, 82{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"},
82{ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"}, 83{ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"},
83{ERR_FUNC(ENGINE_F_ENGINE_FREE), "ENGINE_free"}, 84{ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL), "ENGINE_FREE_UTIL"},
84{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"}, 85{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"},
85{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"}, 86{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"},
86{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"}, 87{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
@@ -91,7 +92,6 @@ static ERR_STRING_DATA ENGINE_str_functs[]=
91{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"}, 92{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"},
92{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"}, 93{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"},
93{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"}, 94{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"},
94{ERR_FUNC(ENGINE_F_ENGINE_MODULE_INIT), "ENGINE_MODULE_INIT"},
95{ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"}, 95{ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"},
96{ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"}, 96{ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"},
97{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), "ENGINE_set_default_string"}, 97{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), "ENGINE_set_default_string"},
@@ -100,11 +100,12 @@ static ERR_STRING_DATA ENGINE_str_functs[]=
100{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"}, 100{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"},
101{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "ENGINE_TABLE_REGISTER"}, 101{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "ENGINE_TABLE_REGISTER"},
102{ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY), "ENGINE_UNLOAD_KEY"}, 102{ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY), "ENGINE_UNLOAD_KEY"},
103{ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "ENGINE_UNLOCKED_FINISH"},
103{ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"}, 104{ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"},
104{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "INT_CTRL_HELPER"}, 105{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "INT_CTRL_HELPER"},
105{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "INT_ENGINE_CONFIGURE"}, 106{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "INT_ENGINE_CONFIGURE"},
107{ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "INT_ENGINE_MODULE_INIT"},
106{ERR_FUNC(ENGINE_F_LOG_MESSAGE), "LOG_MESSAGE"}, 108{ERR_FUNC(ENGINE_F_LOG_MESSAGE), "LOG_MESSAGE"},
107{ERR_FUNC(ENGINE_F_SET_DATA_CTX), "SET_DATA_CTX"},
108{0,NULL} 109{0,NULL}
109 }; 110 };
110 111
@@ -156,15 +157,12 @@ static ERR_STRING_DATA ENGINE_str_reasons[]=
156 157
157void ERR_load_ENGINE_strings(void) 158void ERR_load_ENGINE_strings(void)
158 { 159 {
159 static int init=1; 160#ifndef OPENSSL_NO_ERR
160 161
161 if (init) 162 if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL)
162 { 163 {
163 init=0;
164#ifndef OPENSSL_NO_ERR
165 ERR_load_strings(0,ENGINE_str_functs); 164 ERR_load_strings(0,ENGINE_str_functs);
166 ERR_load_strings(0,ENGINE_str_reasons); 165 ERR_load_strings(0,ENGINE_str_reasons);
167#endif
168
169 } 166 }
167#endif
170 } 168 }
diff --git a/src/lib/libcrypto/engine/eng_fat.c b/src/lib/libcrypto/engine/eng_fat.c
index 7ccf7022ee..27c1662f62 100644
--- a/src/lib/libcrypto/engine/eng_fat.c
+++ b/src/lib/libcrypto/engine/eng_fat.c
@@ -52,11 +52,13 @@
52 * Hudson (tjh@cryptsoft.com). 52 * Hudson (tjh@cryptsoft.com).
53 * 53 *
54 */ 54 */
55/* ====================================================================
56 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
57 * ECDH support in OpenSSL originally developed by
58 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
59 */
55 60
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h" 61#include "eng_int.h"
59#include <openssl/engine.h>
60#include <openssl/conf.h> 62#include <openssl/conf.h>
61 63
62int ENGINE_set_default(ENGINE *e, unsigned int flags) 64int ENGINE_set_default(ENGINE *e, unsigned int flags)
@@ -77,6 +79,14 @@ int ENGINE_set_default(ENGINE *e, unsigned int flags)
77 if((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e)) 79 if((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
78 return 0; 80 return 0;
79#endif 81#endif
82#ifndef OPENSSL_NO_ECDH
83 if((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e))
84 return 0;
85#endif
86#ifndef OPENSSL_NO_ECDSA
87 if((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e))
88 return 0;
89#endif
80 if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) 90 if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
81 return 0; 91 return 0;
82 return 1; 92 return 1;
@@ -93,6 +103,10 @@ static int int_def_cb(const char *alg, int len, void *arg)
93 *pflags |= ENGINE_METHOD_RSA; 103 *pflags |= ENGINE_METHOD_RSA;
94 else if (!strncmp(alg, "DSA", len)) 104 else if (!strncmp(alg, "DSA", len))
95 *pflags |= ENGINE_METHOD_DSA; 105 *pflags |= ENGINE_METHOD_DSA;
106 else if (!strncmp(alg, "ECDH", len))
107 *pflags |= ENGINE_METHOD_ECDH;
108 else if (!strncmp(alg, "ECDSA", len))
109 *pflags |= ENGINE_METHOD_ECDSA;
96 else if (!strncmp(alg, "DH", len)) 110 else if (!strncmp(alg, "DH", len))
97 *pflags |= ENGINE_METHOD_DH; 111 *pflags |= ENGINE_METHOD_DH;
98 else if (!strncmp(alg, "RAND", len)) 112 else if (!strncmp(alg, "RAND", len))
@@ -133,6 +147,12 @@ int ENGINE_register_complete(ENGINE *e)
133#ifndef OPENSSL_NO_DH 147#ifndef OPENSSL_NO_DH
134 ENGINE_register_DH(e); 148 ENGINE_register_DH(e);
135#endif 149#endif
150#ifndef OPENSSL_NO_ECDH
151 ENGINE_register_ECDH(e);
152#endif
153#ifndef OPENSSL_NO_ECDSA
154 ENGINE_register_ECDSA(e);
155#endif
136 ENGINE_register_RAND(e); 156 ENGINE_register_RAND(e);
137 return 1; 157 return 1;
138 } 158 }
diff --git a/src/lib/libcrypto/engine/eng_init.c b/src/lib/libcrypto/engine/eng_init.c
index 170c1791b3..7633cf5f1d 100644
--- a/src/lib/libcrypto/engine/eng_init.c
+++ b/src/lib/libcrypto/engine/eng_init.c
@@ -53,10 +53,7 @@
53 * 53 *
54 */ 54 */
55 55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h" 56#include "eng_int.h"
59#include <openssl/engine.h>
60 57
61/* Initialise a engine type for use (or up its functional reference count 58/* Initialise a engine type for use (or up its functional reference count
62 * if it's already in use). This version is only used internally. */ 59 * if it's already in use). This version is only used internally. */
@@ -114,7 +111,7 @@ int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
114 /* Release the structural reference too */ 111 /* Release the structural reference too */
115 if(!engine_free_util(e, 0)) 112 if(!engine_free_util(e, 0))
116 { 113 {
117 ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED); 114 ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH,ENGINE_R_FINISH_FAILED);
118 return 0; 115 return 0;
119 } 116 }
120 return to_return; 117 return to_return;
diff --git a/src/lib/libcrypto/engine/eng_int.h b/src/lib/libcrypto/engine/eng_int.h
index 38335f99cd..a5b1edebf4 100644
--- a/src/lib/libcrypto/engine/eng_int.h
+++ b/src/lib/libcrypto/engine/eng_int.h
@@ -55,10 +55,16 @@
55 * Hudson (tjh@cryptsoft.com). 55 * Hudson (tjh@cryptsoft.com).
56 * 56 *
57 */ 57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
58 63
59#ifndef HEADER_ENGINE_INT_H 64#ifndef HEADER_ENGINE_INT_H
60#define HEADER_ENGINE_INT_H 65#define HEADER_ENGINE_INT_H
61 66
67#include "cryptlib.h"
62/* Take public definitions from engine.h */ 68/* Take public definitions from engine.h */
63#include <openssl/engine.h> 69#include <openssl/engine.h>
64 70
@@ -146,7 +152,10 @@ struct engine_st
146 const RSA_METHOD *rsa_meth; 152 const RSA_METHOD *rsa_meth;
147 const DSA_METHOD *dsa_meth; 153 const DSA_METHOD *dsa_meth;
148 const DH_METHOD *dh_meth; 154 const DH_METHOD *dh_meth;
155 const ECDH_METHOD *ecdh_meth;
156 const ECDSA_METHOD *ecdsa_meth;
149 const RAND_METHOD *rand_meth; 157 const RAND_METHOD *rand_meth;
158 const STORE_METHOD *store_meth;
150 /* Cipher handling is via this callback */ 159 /* Cipher handling is via this callback */
151 ENGINE_CIPHERS_PTR ciphers; 160 ENGINE_CIPHERS_PTR ciphers;
152 /* Digest handling is via this callback */ 161 /* Digest handling is via this callback */
diff --git a/src/lib/libcrypto/engine/eng_lib.c b/src/lib/libcrypto/engine/eng_lib.c
index a66d0f08af..5815b867f4 100644
--- a/src/lib/libcrypto/engine/eng_lib.c
+++ b/src/lib/libcrypto/engine/eng_lib.c
@@ -56,11 +56,8 @@
56 * 56 *
57 */ 57 */
58 58
59#include <openssl/crypto.h>
60#include "cryptlib.h"
61#include "eng_int.h" 59#include "eng_int.h"
62#include <openssl/rand.h> /* FIXME: This shouldn't be needed */ 60#include <openssl/rand.h>
63#include <openssl/engine.h>
64 61
65/* The "new"/"free" stuff first */ 62/* The "new"/"free" stuff first */
66 63
@@ -92,6 +89,7 @@ void engine_set_all_null(ENGINE *e)
92 e->dsa_meth = NULL; 89 e->dsa_meth = NULL;
93 e->dh_meth = NULL; 90 e->dh_meth = NULL;
94 e->rand_meth = NULL; 91 e->rand_meth = NULL;
92 e->store_meth = NULL;
95 e->ciphers = NULL; 93 e->ciphers = NULL;
96 e->digests = NULL; 94 e->digests = NULL;
97 e->destroy = NULL; 95 e->destroy = NULL;
@@ -110,7 +108,7 @@ int engine_free_util(ENGINE *e, int locked)
110 108
111 if(e == NULL) 109 if(e == NULL)
112 { 110 {
113 ENGINEerr(ENGINE_F_ENGINE_FREE, 111 ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL,
114 ERR_R_PASSED_NULL_PARAMETER); 112 ERR_R_PASSED_NULL_PARAMETER);
115 return 0; 113 return 0;
116 } 114 }
@@ -319,3 +317,13 @@ const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
319 { 317 {
320 return e->cmd_defns; 318 return e->cmd_defns;
321 } 319 }
320
321/* eng_lib.o is pretty much linked into anything that touches ENGINE already, so
322 * put the "static_state" hack here. */
323
324static int internal_static_hack = 0;
325
326void *ENGINE_get_static_state(void)
327 {
328 return &internal_static_hack;
329 }
diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c
index 1cc3217f4c..bd511944ba 100644
--- a/src/lib/libcrypto/engine/eng_list.c
+++ b/src/lib/libcrypto/engine/eng_list.c
@@ -55,11 +55,13 @@
55 * Hudson (tjh@cryptsoft.com). 55 * Hudson (tjh@cryptsoft.com).
56 * 56 *
57 */ 57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
58 63
59#include <openssl/crypto.h>
60#include "cryptlib.h"
61#include "eng_int.h" 64#include "eng_int.h"
62#include <openssl/engine.h>
63 65
64/* The linked-list of pointers to engine types. engine_list_head 66/* The linked-list of pointers to engine types. engine_list_head
65 * incorporates an implicit structural reference but engine_list_tail 67 * incorporates an implicit structural reference but engine_list_tail
@@ -324,7 +326,14 @@ static void engine_cpy(ENGINE *dest, const ENGINE *src)
324#ifndef OPENSSL_NO_DH 326#ifndef OPENSSL_NO_DH
325 dest->dh_meth = src->dh_meth; 327 dest->dh_meth = src->dh_meth;
326#endif 328#endif
329#ifndef OPENSSL_NO_ECDH
330 dest->ecdh_meth = src->ecdh_meth;
331#endif
332#ifndef OPENSSL_NO_ECDSA
333 dest->ecdsa_meth = src->ecdsa_meth;
334#endif
327 dest->rand_meth = src->rand_meth; 335 dest->rand_meth = src->rand_meth;
336 dest->store_meth = src->store_meth;
328 dest->ciphers = src->ciphers; 337 dest->ciphers = src->ciphers;
329 dest->digests = src->digests; 338 dest->digests = src->digests;
330 dest->destroy = src->destroy; 339 dest->destroy = src->destroy;
@@ -340,6 +349,7 @@ static void engine_cpy(ENGINE *dest, const ENGINE *src)
340ENGINE *ENGINE_by_id(const char *id) 349ENGINE *ENGINE_by_id(const char *id)
341 { 350 {
342 ENGINE *iterator; 351 ENGINE *iterator;
352 char *load_dir = NULL;
343 if(id == NULL) 353 if(id == NULL)
344 { 354 {
345 ENGINEerr(ENGINE_F_ENGINE_BY_ID, 355 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
@@ -373,6 +383,7 @@ ENGINE *ENGINE_by_id(const char *id)
373 } 383 }
374 } 384 }
375 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 385 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
386#if 0
376 if(iterator == NULL) 387 if(iterator == NULL)
377 { 388 {
378 ENGINEerr(ENGINE_F_ENGINE_BY_ID, 389 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
@@ -380,6 +391,32 @@ ENGINE *ENGINE_by_id(const char *id)
380 ERR_add_error_data(2, "id=", id); 391 ERR_add_error_data(2, "id=", id);
381 } 392 }
382 return iterator; 393 return iterator;
394#else
395 /* EEK! Experimental code starts */
396 if(iterator) return iterator;
397 /* Prevent infinite recusrion if we're looking for the dynamic engine. */
398 if (strcmp(id, "dynamic"))
399 {
400#ifdef OPENSSL_SYS_VMS
401 if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
402#else
403 if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
404#endif
405 iterator = ENGINE_by_id("dynamic");
406 if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
407 !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
408 !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
409 load_dir, 0) ||
410 !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
411 goto notfound;
412 return iterator;
413 }
414notfound:
415 ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
416 ERR_add_error_data(2, "id=", id);
417 return NULL;
418 /* EEK! Experimental code ends */
419#endif
383 } 420 }
384 421
385int ENGINE_up_ref(ENGINE *e) 422int ENGINE_up_ref(ENGINE *e)
diff --git a/src/lib/libcrypto/engine/eng_openssl.c b/src/lib/libcrypto/engine/eng_openssl.c
index 54579eea2e..7c139ae2ef 100644
--- a/src/lib/libcrypto/engine/eng_openssl.c
+++ b/src/lib/libcrypto/engine/eng_openssl.c
@@ -55,6 +55,11 @@
55 * Hudson (tjh@cryptsoft.com). 55 * Hudson (tjh@cryptsoft.com).
56 * 56 *
57 */ 57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
58 63
59 64
60#include <stdio.h> 65#include <stdio.h>
@@ -64,6 +69,16 @@
64#include <openssl/dso.h> 69#include <openssl/dso.h>
65#include <openssl/pem.h> 70#include <openssl/pem.h>
66#include <openssl/evp.h> 71#include <openssl/evp.h>
72#include <openssl/rand.h>
73#ifndef OPENSSL_NO_RSA
74#include <openssl/rsa.h>
75#endif
76#ifndef OPENSSL_NO_DSA
77#include <openssl/dsa.h>
78#endif
79#ifndef OPENSSL_NO_DH
80#include <openssl/dh.h>
81#endif
67 82
68/* This testing gunk is implemented (and explained) lower down. It also assumes 83/* This testing gunk is implemented (and explained) lower down. It also assumes
69 * the application explicitly calls "ENGINE_load_openssl()" because this is no 84 * the application explicitly calls "ENGINE_load_openssl()" because this is no
@@ -125,6 +140,12 @@ static int bind_helper(ENGINE *e)
125#ifndef OPENSSL_NO_DSA 140#ifndef OPENSSL_NO_DSA
126 || !ENGINE_set_DSA(e, DSA_get_default_method()) 141 || !ENGINE_set_DSA(e, DSA_get_default_method())
127#endif 142#endif
143#ifndef OPENSSL_NO_ECDH
144 || !ENGINE_set_ECDH(e, ECDH_OpenSSL())
145#endif
146#ifndef OPENSSL_NO_ECDSA
147 || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
148#endif
128#ifndef OPENSSL_NO_DH 149#ifndef OPENSSL_NO_DH
129 || !ENGINE_set_DH(e, DH_get_default_method()) 150 || !ENGINE_set_DH(e, DH_get_default_method())
130#endif 151#endif
@@ -236,6 +257,7 @@ static const EVP_CIPHER test_r4_cipher=
236 sizeof(TEST_RC4_KEY), 257 sizeof(TEST_RC4_KEY),
237 NULL, 258 NULL,
238 NULL, 259 NULL,
260 NULL,
239 NULL 261 NULL
240 }; 262 };
241static const EVP_CIPHER test_r4_40_cipher= 263static const EVP_CIPHER test_r4_40_cipher=
@@ -249,6 +271,7 @@ static const EVP_CIPHER test_r4_40_cipher=
249 sizeof(TEST_RC4_KEY), 271 sizeof(TEST_RC4_KEY),
250 NULL, 272 NULL,
251 NULL, 273 NULL,
274 NULL,
252 NULL 275 NULL
253 }; 276 };
254static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 277static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
@@ -290,7 +313,7 @@ static int test_sha1_init(EVP_MD_CTX *ctx)
290#endif 313#endif
291 return SHA1_Init(ctx->md_data); 314 return SHA1_Init(ctx->md_data);
292 } 315 }
293static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,unsigned long count) 316static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,size_t count)
294 { 317 {
295#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE 318#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
296 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n"); 319 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
diff --git a/src/lib/libcrypto/engine/eng_padlock.c b/src/lib/libcrypto/engine/eng_padlock.c
new file mode 100644
index 0000000000..1ba9d85db4
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_padlock.c
@@ -0,0 +1,1219 @@
1/*
2 * Support for VIA PadLock Advanced Cryptography Engine (ACE)
3 * Written by Michal Ludvig <michal@logix.cz>
4 * http://www.logix.cz/michal
5 *
6 * Big thanks to Andy Polyakov for a help with optimization,
7 * assembler fixes, port to MS Windows and a lot of other
8 * valuable work on this engine!
9 */
10
11/* ====================================================================
12 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in
23 * the documentation and/or other materials provided with the
24 * distribution.
25 *
26 * 3. All advertising materials mentioning features or use of this
27 * software must display the following acknowledgment:
28 * "This product includes software developed by the OpenSSL Project
29 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
30 *
31 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
32 * endorse or promote products derived from this software without
33 * prior written permission. For written permission, please contact
34 * licensing@OpenSSL.org.
35 *
36 * 5. Products derived from this software may not be called "OpenSSL"
37 * nor may "OpenSSL" appear in their names without prior written
38 * permission of the OpenSSL Project.
39 *
40 * 6. Redistributions of any form whatsoever must retain the following
41 * acknowledgment:
42 * "This product includes software developed by the OpenSSL Project
43 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
46 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56 * OF THE POSSIBILITY OF SUCH DAMAGE.
57 * ====================================================================
58 *
59 * This product includes cryptographic software written by Eric Young
60 * (eay@cryptsoft.com). This product includes software written by Tim
61 * Hudson (tjh@cryptsoft.com).
62 *
63 */
64
65
66#include <stdio.h>
67#include <string.h>
68
69#include <openssl/opensslconf.h>
70#include <openssl/crypto.h>
71#include <openssl/dso.h>
72#include <openssl/engine.h>
73#include <openssl/evp.h>
74#ifndef OPENSSL_NO_AES
75#include <openssl/aes.h>
76#endif
77#include <openssl/rand.h>
78#include <openssl/err.h>
79
80#ifndef OPENSSL_NO_HW
81#ifndef OPENSSL_NO_HW_PADLOCK
82
83/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
84#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
85# ifndef OPENSSL_NO_DYNAMIC_ENGINE
86# define DYNAMIC_ENGINE
87# endif
88#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
89# ifdef ENGINE_DYNAMIC_SUPPORT
90# define DYNAMIC_ENGINE
91# endif
92#else
93# error "Only OpenSSL >= 0.9.7 is supported"
94#endif
95
96/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
97 Not only that it doesn't exist elsewhere, but it
98 even can't be compiled on other platforms!
99
100 In addition, because of the heavy use of inline assembler,
101 compiler choice is limited to GCC and Microsoft C. */
102#undef COMPILE_HW_PADLOCK
103#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
104# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
105 (defined(_MSC_VER) && defined(_M_IX86))
106# define COMPILE_HW_PADLOCK
107static ENGINE *ENGINE_padlock (void);
108# endif
109#endif
110
111void ENGINE_load_padlock (void)
112{
113/* On non-x86 CPUs it just returns. */
114#ifdef COMPILE_HW_PADLOCK
115 ENGINE *toadd = ENGINE_padlock ();
116 if (!toadd) return;
117 ENGINE_add (toadd);
118 ENGINE_free (toadd);
119 ERR_clear_error ();
120#endif
121}
122
123#ifdef COMPILE_HW_PADLOCK
124/* We do these includes here to avoid header problems on platforms that
125 do not have the VIA padlock anyway... */
126#ifdef _MSC_VER
127# include <malloc.h>
128# define alloca _alloca
129#elif defined(NETWARE_CLIB) && defined(__GNUC__)
130 void *alloca(size_t);
131# define alloca(s) __builtin_alloca(s)
132#else
133# include <stdlib.h>
134#endif
135
136/* Function for ENGINE detection and control */
137static int padlock_available(void);
138static int padlock_init(ENGINE *e);
139
140/* RNG Stuff */
141static RAND_METHOD padlock_rand;
142
143/* Cipher Stuff */
144#ifndef OPENSSL_NO_AES
145static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
146#endif
147
148/* Engine names */
149static const char *padlock_id = "padlock";
150static char padlock_name[100];
151
152/* Available features */
153static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
154static int padlock_use_rng = 0; /* Random Number Generator */
155#ifndef OPENSSL_NO_AES
156static int padlock_aes_align_required = 1;
157#endif
158
159/* ===== Engine "management" functions ===== */
160
161/* Prepare the ENGINE structure for registration */
162static int
163padlock_bind_helper(ENGINE *e)
164{
165 /* Check available features */
166 padlock_available();
167
168#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
169 padlock_use_rng=0;
170#endif
171
172 /* Generate a nice engine name with available features */
173 BIO_snprintf(padlock_name, sizeof(padlock_name),
174 "VIA PadLock (%s, %s)",
175 padlock_use_rng ? "RNG" : "no-RNG",
176 padlock_use_ace ? "ACE" : "no-ACE");
177
178 /* Register everything or return with an error */
179 if (!ENGINE_set_id(e, padlock_id) ||
180 !ENGINE_set_name(e, padlock_name) ||
181
182 !ENGINE_set_init_function(e, padlock_init) ||
183#ifndef OPENSSL_NO_AES
184 (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
185#endif
186 (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
187 return 0;
188 }
189
190 /* Everything looks good */
191 return 1;
192}
193
194/* Constructor */
195static ENGINE *
196ENGINE_padlock(void)
197{
198 ENGINE *eng = ENGINE_new();
199
200 if (!eng) {
201 return NULL;
202 }
203
204 if (!padlock_bind_helper(eng)) {
205 ENGINE_free(eng);
206 return NULL;
207 }
208
209 return eng;
210}
211
212/* Check availability of the engine */
213static int
214padlock_init(ENGINE *e)
215{
216 return (padlock_use_rng || padlock_use_ace);
217}
218
219/* This stuff is needed if this ENGINE is being compiled into a self-contained
220 * shared-library.
221 */
222#ifdef DYNAMIC_ENGINE
223static int
224padlock_bind_fn(ENGINE *e, const char *id)
225{
226 if (id && (strcmp(id, padlock_id) != 0)) {
227 return 0;
228 }
229
230 if (!padlock_bind_helper(e)) {
231 return 0;
232 }
233
234 return 1;
235}
236
237IMPLEMENT_DYNAMIC_CHECK_FN ();
238IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn);
239#endif /* DYNAMIC_ENGINE */
240
241/* ===== Here comes the "real" engine ===== */
242
243#ifndef OPENSSL_NO_AES
244/* Some AES-related constants */
245#define AES_BLOCK_SIZE 16
246#define AES_KEY_SIZE_128 16
247#define AES_KEY_SIZE_192 24
248#define AES_KEY_SIZE_256 32
249
250/* Here we store the status information relevant to the
251 current context. */
252/* BIG FAT WARNING:
253 * Inline assembler in PADLOCK_XCRYPT_ASM()
254 * depends on the order of items in this structure.
255 * Don't blindly modify, reorder, etc!
256 */
257struct padlock_cipher_data
258{
259 unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */
260 union { unsigned int pad[4];
261 struct {
262 int rounds:4;
263 int dgst:1; /* n/a in C3 */
264 int align:1; /* n/a in C3 */
265 int ciphr:1; /* n/a in C3 */
266 unsigned int keygen:1;
267 int interm:1;
268 unsigned int encdec:1;
269 int ksize:2;
270 } b;
271 } cword; /* Control word */
272 AES_KEY ks; /* Encryption key */
273};
274
275/*
276 * Essentially this variable belongs in thread local storage.
277 * Having this variable global on the other hand can only cause
278 * few bogus key reloads [if any at all on single-CPU system],
279 * so we accept the penatly...
280 */
281static volatile struct padlock_cipher_data *padlock_saved_context;
282#endif
283
284/*
285 * =======================================================
286 * Inline assembler section(s).
287 * =======================================================
288 * Order of arguments is chosen to facilitate Windows port
289 * using __fastcall calling convention. If you wish to add
290 * more routines, keep in mind that first __fastcall
291 * argument is passed in %ecx and second - in %edx.
292 * =======================================================
293 */
294#if defined(__GNUC__) && __GNUC__>=2
295/*
296 * As for excessive "push %ebx"/"pop %ebx" found all over.
297 * When generating position-independent code GCC won't let
298 * us use "b" in assembler templates nor even respect "ebx"
299 * in "clobber description." Therefore the trouble...
300 */
301
302/* Helper function - check if a CPUID instruction
303 is available on this CPU */
304static int
305padlock_insn_cpuid_available(void)
306{
307 int result = -1;
308
309 /* We're checking if the bit #21 of EFLAGS
310 can be toggled. If yes = CPUID is available. */
311 asm volatile (
312 "pushf\n"
313 "popl %%eax\n"
314 "xorl $0x200000, %%eax\n"
315 "movl %%eax, %%ecx\n"
316 "andl $0x200000, %%ecx\n"
317 "pushl %%eax\n"
318 "popf\n"
319 "pushf\n"
320 "popl %%eax\n"
321 "andl $0x200000, %%eax\n"
322 "xorl %%eax, %%ecx\n"
323 "movl %%ecx, %0\n"
324 : "=r" (result) : : "eax", "ecx");
325
326 return (result == 0);
327}
328
329/* Load supported features of the CPU to see if
330 the PadLock is available. */
331static int
332padlock_available(void)
333{
334 char vendor_string[16];
335 unsigned int eax, edx;
336
337 /* First check if the CPUID instruction is available at all... */
338 if (! padlock_insn_cpuid_available())
339 return 0;
340
341 /* Are we running on the Centaur (VIA) CPU? */
342 eax = 0x00000000;
343 vendor_string[12] = 0;
344 asm volatile (
345 "pushl %%ebx\n"
346 "cpuid\n"
347 "movl %%ebx,(%%edi)\n"
348 "movl %%edx,4(%%edi)\n"
349 "movl %%ecx,8(%%edi)\n"
350 "popl %%ebx"
351 : "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
352 if (strcmp(vendor_string, "CentaurHauls") != 0)
353 return 0;
354
355 /* Check for Centaur Extended Feature Flags presence */
356 eax = 0xC0000000;
357 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
358 : "+a"(eax) : : "ecx", "edx");
359 if (eax < 0xC0000001)
360 return 0;
361
362 /* Read the Centaur Extended Feature Flags */
363 eax = 0xC0000001;
364 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
365 : "+a"(eax), "=d"(edx) : : "ecx");
366
367 /* Fill up some flags */
368 padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
369 padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
370
371 return padlock_use_ace + padlock_use_rng;
372}
373
374#ifndef OPENSSL_NO_AES
375/* Our own htonl()/ntohl() */
376static inline void
377padlock_bswapl(AES_KEY *ks)
378{
379 size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
380 unsigned int *key = ks->rd_key;
381
382 while (i--) {
383 asm volatile ("bswapl %0" : "+r"(*key));
384 key++;
385 }
386}
387#endif
388
389/* Force key reload from memory to the CPU microcode.
390 Loading EFLAGS from the stack clears EFLAGS[30]
391 which does the trick. */
392static inline void
393padlock_reload_key(void)
394{
395 asm volatile ("pushfl; popfl");
396}
397
398#ifndef OPENSSL_NO_AES
399/*
400 * This is heuristic key context tracing. At first one
401 * believes that one should use atomic swap instructions,
402 * but it's not actually necessary. Point is that if
403 * padlock_saved_context was changed by another thread
404 * after we've read it and before we compare it with cdata,
405 * our key *shall* be reloaded upon thread context switch
406 * and we are therefore set in either case...
407 */
408static inline void
409padlock_verify_context(struct padlock_cipher_data *cdata)
410{
411 asm volatile (
412 "pushfl\n"
413" btl $30,(%%esp)\n"
414" jnc 1f\n"
415" cmpl %2,%1\n"
416" je 1f\n"
417" popfl\n"
418" subl $4,%%esp\n"
419"1: addl $4,%%esp\n"
420" movl %2,%0"
421 :"+m"(padlock_saved_context)
422 : "r"(padlock_saved_context), "r"(cdata) : "cc");
423}
424
425/* Template for padlock_xcrypt_* modes */
426/* BIG FAT WARNING:
427 * The offsets used with 'leal' instructions
428 * describe items of the 'padlock_cipher_data'
429 * structure.
430 */
431#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \
432static inline void *name(size_t cnt, \
433 struct padlock_cipher_data *cdata, \
434 void *out, const void *inp) \
435{ void *iv; \
436 asm volatile ( "pushl %%ebx\n" \
437 " leal 16(%0),%%edx\n" \
438 " leal 32(%0),%%ebx\n" \
439 rep_xcrypt "\n" \
440 " popl %%ebx" \
441 : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
442 : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
443 : "edx", "cc", "memory"); \
444 return iv; \
445}
446
447/* Generate all functions with appropriate opcodes */
448PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */
449PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */
450PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */
451PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */
452#endif
453
454/* The RNG call itself */
455static inline unsigned int
456padlock_xstore(void *addr, unsigned int edx_in)
457{
458 unsigned int eax_out;
459
460 asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */
461 : "=a"(eax_out),"=m"(*(unsigned *)addr)
462 : "D"(addr), "d" (edx_in)
463 );
464
465 return eax_out;
466}
467
468/* Why not inline 'rep movsd'? I failed to find information on what
469 * value in Direction Flag one can expect and consequently have to
470 * apply "better-safe-than-sorry" approach and assume "undefined."
471 * I could explicitly clear it and restore the original value upon
472 * return from padlock_aes_cipher, but it's presumably too much
473 * trouble for too little gain...
474 *
475 * In case you wonder 'rep xcrypt*' instructions above are *not*
476 * affected by the Direction Flag and pointers advance toward
477 * larger addresses unconditionally.
478 */
479static inline unsigned char *
480padlock_memcpy(void *dst,const void *src,size_t n)
481{
482 long *d=dst;
483 const long *s=src;
484
485 n /= sizeof(*d);
486 do { *d++ = *s++; } while (--n);
487
488 return dst;
489}
490
491#elif defined(_MSC_VER)
492/*
493 * Unlike GCC these are real functions. In order to minimize impact
494 * on performance we adhere to __fastcall calling convention in
495 * order to get two first arguments passed through %ecx and %edx.
496 * Which kind of suits very well, as instructions in question use
497 * both %ecx and %edx as input:-)
498 */
499#define REP_XCRYPT(code) \
500 _asm _emit 0xf3 \
501 _asm _emit 0x0f _asm _emit 0xa7 \
502 _asm _emit code
503
504/* BIG FAT WARNING:
505 * The offsets used with 'lea' instructions
506 * describe items of the 'padlock_cipher_data'
507 * structure.
508 */
509#define PADLOCK_XCRYPT_ASM(name,code) \
510static void * __fastcall \
511 name (size_t cnt, void *cdata, \
512 void *outp, const void *inp) \
513{ _asm mov eax,edx \
514 _asm lea edx,[eax+16] \
515 _asm lea ebx,[eax+32] \
516 _asm mov edi,outp \
517 _asm mov esi,inp \
518 REP_XCRYPT(code) \
519}
520
521PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
522PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
523PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
524PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
525
526static int __fastcall
527padlock_xstore(void *outp,unsigned int code)
528{ _asm mov edi,ecx
529 _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
530}
531
532static void __fastcall
533padlock_reload_key(void)
534{ _asm pushfd _asm popfd }
535
536static void __fastcall
537padlock_verify_context(void *cdata)
538{ _asm {
539 pushfd
540 bt DWORD PTR[esp],30
541 jnc skip
542 cmp ecx,padlock_saved_context
543 je skip
544 popfd
545 sub esp,4
546 skip: add esp,4
547 mov padlock_saved_context,ecx
548 }
549}
550
551static int
552padlock_available(void)
553{ _asm {
554 pushfd
555 pop eax
556 mov ecx,eax
557 xor eax,1<<21
558 push eax
559 popfd
560 pushfd
561 pop eax
562 xor eax,ecx
563 bt eax,21
564 jnc noluck
565 mov eax,0
566 cpuid
567 xor eax,eax
568 cmp ebx,'tneC'
569 jne noluck
570 cmp edx,'Hrua'
571 jne noluck
572 cmp ecx,'slua'
573 jne noluck
574 mov eax,0xC0000000
575 cpuid
576 mov edx,eax
577 xor eax,eax
578 cmp edx,0xC0000001
579 jb noluck
580 mov eax,0xC0000001
581 cpuid
582 xor eax,eax
583 bt edx,6
584 jnc skip_a
585 bt edx,7
586 jnc skip_a
587 mov padlock_use_ace,1
588 inc eax
589 skip_a: bt edx,2
590 jnc skip_r
591 bt edx,3
592 jnc skip_r
593 mov padlock_use_rng,1
594 inc eax
595 skip_r:
596 noluck:
597 }
598}
599
600static void __fastcall
601padlock_bswapl(void *key)
602{ _asm {
603 pushfd
604 cld
605 mov esi,ecx
606 mov edi,ecx
607 mov ecx,60
608 up: lodsd
609 bswap eax
610 stosd
611 loop up
612 popfd
613 }
614}
615
616/* MS actually specifies status of Direction Flag and compiler even
617 * manages to compile following as 'rep movsd' all by itself...
618 */
619#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
620#endif
621
622/* ===== AES encryption/decryption ===== */
623#ifndef OPENSSL_NO_AES
624
625#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
626#define NID_aes_128_cfb NID_aes_128_cfb128
627#endif
628
629#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
630#define NID_aes_128_ofb NID_aes_128_ofb128
631#endif
632
633#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
634#define NID_aes_192_cfb NID_aes_192_cfb128
635#endif
636
637#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
638#define NID_aes_192_ofb NID_aes_192_ofb128
639#endif
640
641#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
642#define NID_aes_256_cfb NID_aes_256_cfb128
643#endif
644
645#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
646#define NID_aes_256_ofb NID_aes_256_ofb128
647#endif
648
649/* List of supported ciphers. */
650static int padlock_cipher_nids[] = {
651 NID_aes_128_ecb,
652 NID_aes_128_cbc,
653 NID_aes_128_cfb,
654 NID_aes_128_ofb,
655
656 NID_aes_192_ecb,
657 NID_aes_192_cbc,
658 NID_aes_192_cfb,
659 NID_aes_192_ofb,
660
661 NID_aes_256_ecb,
662 NID_aes_256_cbc,
663 NID_aes_256_cfb,
664 NID_aes_256_ofb,
665};
666static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
667 sizeof(padlock_cipher_nids[0]));
668
669/* Function prototypes ... */
670static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
671 const unsigned char *iv, int enc);
672static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
673 const unsigned char *in, size_t nbytes);
674
675#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
676 ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
677#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
678 NEAREST_ALIGNED(ctx->cipher_data))
679
680#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
681#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
682#define EVP_CIPHER_block_size_OFB 1
683#define EVP_CIPHER_block_size_CFB 1
684
685/* Declaring so many ciphers by hand would be a pain.
686 Instead introduce a bit of preprocessor magic :-) */
687#define DECLARE_AES_EVP(ksize,lmode,umode) \
688static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
689 NID_aes_##ksize##_##lmode, \
690 EVP_CIPHER_block_size_##umode, \
691 AES_KEY_SIZE_##ksize, \
692 AES_BLOCK_SIZE, \
693 0 | EVP_CIPH_##umode##_MODE, \
694 padlock_aes_init_key, \
695 padlock_aes_cipher, \
696 NULL, \
697 sizeof(struct padlock_cipher_data) + 16, \
698 EVP_CIPHER_set_asn1_iv, \
699 EVP_CIPHER_get_asn1_iv, \
700 NULL, \
701 NULL \
702}
703
704DECLARE_AES_EVP(128,ecb,ECB);
705DECLARE_AES_EVP(128,cbc,CBC);
706DECLARE_AES_EVP(128,cfb,CFB);
707DECLARE_AES_EVP(128,ofb,OFB);
708
709DECLARE_AES_EVP(192,ecb,ECB);
710DECLARE_AES_EVP(192,cbc,CBC);
711DECLARE_AES_EVP(192,cfb,CFB);
712DECLARE_AES_EVP(192,ofb,OFB);
713
714DECLARE_AES_EVP(256,ecb,ECB);
715DECLARE_AES_EVP(256,cbc,CBC);
716DECLARE_AES_EVP(256,cfb,CFB);
717DECLARE_AES_EVP(256,ofb,OFB);
718
719static int
720padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
721{
722 /* No specific cipher => return a list of supported nids ... */
723 if (!cipher) {
724 *nids = padlock_cipher_nids;
725 return padlock_cipher_nids_num;
726 }
727
728 /* ... or the requested "cipher" otherwise */
729 switch (nid) {
730 case NID_aes_128_ecb:
731 *cipher = &padlock_aes_128_ecb;
732 break;
733 case NID_aes_128_cbc:
734 *cipher = &padlock_aes_128_cbc;
735 break;
736 case NID_aes_128_cfb:
737 *cipher = &padlock_aes_128_cfb;
738 break;
739 case NID_aes_128_ofb:
740 *cipher = &padlock_aes_128_ofb;
741 break;
742
743 case NID_aes_192_ecb:
744 *cipher = &padlock_aes_192_ecb;
745 break;
746 case NID_aes_192_cbc:
747 *cipher = &padlock_aes_192_cbc;
748 break;
749 case NID_aes_192_cfb:
750 *cipher = &padlock_aes_192_cfb;
751 break;
752 case NID_aes_192_ofb:
753 *cipher = &padlock_aes_192_ofb;
754 break;
755
756 case NID_aes_256_ecb:
757 *cipher = &padlock_aes_256_ecb;
758 break;
759 case NID_aes_256_cbc:
760 *cipher = &padlock_aes_256_cbc;
761 break;
762 case NID_aes_256_cfb:
763 *cipher = &padlock_aes_256_cfb;
764 break;
765 case NID_aes_256_ofb:
766 *cipher = &padlock_aes_256_ofb;
767 break;
768
769 default:
770 /* Sorry, we don't support this NID */
771 *cipher = NULL;
772 return 0;
773 }
774
775 return 1;
776}
777
778/* Prepare the encryption key for PadLock usage */
779static int
780padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
781 const unsigned char *iv, int enc)
782{
783 struct padlock_cipher_data *cdata;
784 int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
785
786 if (key==NULL) return 0; /* ERROR */
787
788 cdata = ALIGNED_CIPHER_DATA(ctx);
789 memset(cdata, 0, sizeof(struct padlock_cipher_data));
790
791 /* Prepare Control word. */
792 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
793 cdata->cword.b.encdec = 0;
794 else
795 cdata->cword.b.encdec = (ctx->encrypt == 0);
796 cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
797 cdata->cword.b.ksize = (key_len - 128) / 64;
798
799 switch(key_len) {
800 case 128:
801 /* PadLock can generate an extended key for
802 AES128 in hardware */
803 memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
804 cdata->cword.b.keygen = 0;
805 break;
806
807 case 192:
808 case 256:
809 /* Generate an extended AES key in software.
810 Needed for AES192/AES256 */
811 /* Well, the above applies to Stepping 8 CPUs
812 and is listed as hardware errata. They most
813 likely will fix it at some point and then
814 a check for stepping would be due here. */
815 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
816 EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
817 enc)
818 AES_set_encrypt_key(key, key_len, &cdata->ks);
819 else
820 AES_set_decrypt_key(key, key_len, &cdata->ks);
821#ifndef AES_ASM
822 /* OpenSSL C functions use byte-swapped extended key. */
823 padlock_bswapl(&cdata->ks);
824#endif
825 cdata->cword.b.keygen = 1;
826 break;
827
828 default:
829 /* ERROR */
830 return 0;
831 }
832
833 /*
834 * This is done to cover for cases when user reuses the
835 * context for new key. The catch is that if we don't do
836 * this, padlock_eas_cipher might proceed with old key...
837 */
838 padlock_reload_key ();
839
840 return 1;
841}
842
843/*
844 * Simplified version of padlock_aes_cipher() used when
845 * 1) both input and output buffers are at aligned addresses.
846 * or when
847 * 2) running on a newer CPU that doesn't require aligned buffers.
848 */
849static int
850padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
851 const unsigned char *in_arg, size_t nbytes)
852{
853 struct padlock_cipher_data *cdata;
854 void *iv;
855
856 cdata = ALIGNED_CIPHER_DATA(ctx);
857 padlock_verify_context(cdata);
858
859 switch (EVP_CIPHER_CTX_mode(ctx)) {
860 case EVP_CIPH_ECB_MODE:
861 padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
862 break;
863
864 case EVP_CIPH_CBC_MODE:
865 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
866 iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
867 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
868 break;
869
870 case EVP_CIPH_CFB_MODE:
871 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
872 iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
873 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
874 break;
875
876 case EVP_CIPH_OFB_MODE:
877 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
878 padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
879 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
880 break;
881
882 default:
883 return 0;
884 }
885
886 memset(cdata->iv, 0, AES_BLOCK_SIZE);
887
888 return 1;
889}
890
891#ifndef PADLOCK_CHUNK
892# define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */
893#endif
894#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
895# error "insane PADLOCK_CHUNK..."
896#endif
897
898/* Re-align the arguments to 16-Bytes boundaries and run the
899 encryption function itself. This function is not AES-specific. */
900static int
901padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
902 const unsigned char *in_arg, size_t nbytes)
903{
904 struct padlock_cipher_data *cdata;
905 const void *inp;
906 unsigned char *out;
907 void *iv;
908 int inp_misaligned, out_misaligned, realign_in_loop;
909 size_t chunk, allocated=0;
910
911 /* ctx->num is maintained in byte-oriented modes,
912 such as CFB and OFB... */
913 if ((chunk = ctx->num)) { /* borrow chunk variable */
914 unsigned char *ivp=ctx->iv;
915
916 switch (EVP_CIPHER_CTX_mode(ctx)) {
917 case EVP_CIPH_CFB_MODE:
918 if (chunk >= AES_BLOCK_SIZE)
919 return 0; /* bogus value */
920
921 if (ctx->encrypt)
922 while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
923 ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
924 chunk++, nbytes--;
925 }
926 else while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
927 unsigned char c = *(in_arg++);
928 *(out_arg++) = c ^ ivp[chunk];
929 ivp[chunk++] = c, nbytes--;
930 }
931
932 ctx->num = chunk%AES_BLOCK_SIZE;
933 break;
934 case EVP_CIPH_OFB_MODE:
935 if (chunk >= AES_BLOCK_SIZE)
936 return 0; /* bogus value */
937
938 while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
939 *(out_arg++) = *(in_arg++) ^ ivp[chunk];
940 chunk++, nbytes--;
941 }
942
943 ctx->num = chunk%AES_BLOCK_SIZE;
944 break;
945 }
946 }
947
948 if (nbytes == 0)
949 return 1;
950#if 0
951 if (nbytes % AES_BLOCK_SIZE)
952 return 0; /* are we expected to do tail processing? */
953#else
954 /* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
955 modes and arbitrary value in byte-oriented modes, such as
956 CFB and OFB... */
957#endif
958
959 /* VIA promises CPUs that won't require alignment in the future.
960 For now padlock_aes_align_required is initialized to 1 and
961 the condition is never met... */
962 /* C7 core is capable to manage unaligned input in non-ECB[!]
963 mode, but performance penalties appear to be approximately
964 same as for software alignment below or ~3x. They promise to
965 improve it in the future, but for now we can just as well
966 pretend that it can only handle aligned input... */
967 if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
968 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
969
970 inp_misaligned = (((size_t)in_arg) & 0x0F);
971 out_misaligned = (((size_t)out_arg) & 0x0F);
972
973 /* Note that even if output is aligned and input not,
974 * I still prefer to loop instead of copy the whole
975 * input and then encrypt in one stroke. This is done
976 * in order to improve L1 cache utilization... */
977 realign_in_loop = out_misaligned|inp_misaligned;
978
979 if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
980 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
981
982 /* this takes one "if" out of the loops */
983 chunk = nbytes;
984 chunk %= PADLOCK_CHUNK;
985 if (chunk==0) chunk = PADLOCK_CHUNK;
986
987 if (out_misaligned) {
988 /* optmize for small input */
989 allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
990 out = alloca(0x10 + allocated);
991 out = NEAREST_ALIGNED(out);
992 }
993 else
994 out = out_arg;
995
996 cdata = ALIGNED_CIPHER_DATA(ctx);
997 padlock_verify_context(cdata);
998
999 switch (EVP_CIPHER_CTX_mode(ctx)) {
1000 case EVP_CIPH_ECB_MODE:
1001 do {
1002 if (inp_misaligned)
1003 inp = padlock_memcpy(out, in_arg, chunk);
1004 else
1005 inp = in_arg;
1006 in_arg += chunk;
1007
1008 padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1009
1010 if (out_misaligned)
1011 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1012 else
1013 out = out_arg+=chunk;
1014
1015 nbytes -= chunk;
1016 chunk = PADLOCK_CHUNK;
1017 } while (nbytes);
1018 break;
1019
1020 case EVP_CIPH_CBC_MODE:
1021 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1022 goto cbc_shortcut;
1023 do {
1024 if (iv != cdata->iv)
1025 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1026 chunk = PADLOCK_CHUNK;
1027 cbc_shortcut: /* optimize for small input */
1028 if (inp_misaligned)
1029 inp = padlock_memcpy(out, in_arg, chunk);
1030 else
1031 inp = in_arg;
1032 in_arg += chunk;
1033
1034 iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1035
1036 if (out_misaligned)
1037 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1038 else
1039 out = out_arg+=chunk;
1040
1041 } while (nbytes -= chunk);
1042 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
1043 break;
1044
1045 case EVP_CIPH_CFB_MODE:
1046 memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1047 chunk &= ~(AES_BLOCK_SIZE-1);
1048 if (chunk) goto cfb_shortcut;
1049 else goto cfb_skiploop;
1050 do {
1051 if (iv != cdata->iv)
1052 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1053 chunk = PADLOCK_CHUNK;
1054 cfb_shortcut: /* optimize for small input */
1055 if (inp_misaligned)
1056 inp = padlock_memcpy(out, in_arg, chunk);
1057 else
1058 inp = in_arg;
1059 in_arg += chunk;
1060
1061 iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1062
1063 if (out_misaligned)
1064 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1065 else
1066 out = out_arg+=chunk;
1067
1068 nbytes -= chunk;
1069 } while (nbytes >= AES_BLOCK_SIZE);
1070
1071 cfb_skiploop:
1072 if (nbytes) {
1073 unsigned char *ivp = cdata->iv;
1074
1075 if (iv != ivp) {
1076 memcpy(ivp, iv, AES_BLOCK_SIZE);
1077 iv = ivp;
1078 }
1079 ctx->num = nbytes;
1080 if (cdata->cword.b.encdec) {
1081 cdata->cword.b.encdec=0;
1082 padlock_reload_key();
1083 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1084 cdata->cword.b.encdec=1;
1085 padlock_reload_key();
1086 while(nbytes) {
1087 unsigned char c = *(in_arg++);
1088 *(out_arg++) = c ^ *ivp;
1089 *(ivp++) = c, nbytes--;
1090 }
1091 }
1092 else { padlock_reload_key();
1093 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1094 padlock_reload_key();
1095 while (nbytes) {
1096 *ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
1097 ivp++, nbytes--;
1098 }
1099 }
1100 }
1101
1102 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
1103 break;
1104
1105 case EVP_CIPH_OFB_MODE:
1106 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1107 chunk &= ~(AES_BLOCK_SIZE-1);
1108 if (chunk) do {
1109 if (inp_misaligned)
1110 inp = padlock_memcpy(out, in_arg, chunk);
1111 else
1112 inp = in_arg;
1113 in_arg += chunk;
1114
1115 padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1116
1117 if (out_misaligned)
1118 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1119 else
1120 out = out_arg+=chunk;
1121
1122 nbytes -= chunk;
1123 chunk = PADLOCK_CHUNK;
1124 } while (nbytes >= AES_BLOCK_SIZE);
1125
1126 if (nbytes) {
1127 unsigned char *ivp = cdata->iv;
1128
1129 ctx->num = nbytes;
1130 padlock_reload_key(); /* empirically found */
1131 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1132 padlock_reload_key(); /* empirically found */
1133 while (nbytes) {
1134 *(out_arg++) = *(in_arg++) ^ *ivp;
1135 ivp++, nbytes--;
1136 }
1137 }
1138
1139 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
1140 break;
1141
1142 default:
1143 return 0;
1144 }
1145
1146 /* Clean the realign buffer if it was used */
1147 if (out_misaligned) {
1148 volatile unsigned long *p=(void *)out;
1149 size_t n = allocated/sizeof(*p);
1150 while (n--) *p++=0;
1151 }
1152
1153 memset(cdata->iv, 0, AES_BLOCK_SIZE);
1154
1155 return 1;
1156}
1157
1158#endif /* OPENSSL_NO_AES */
1159
1160/* ===== Random Number Generator ===== */
1161/*
1162 * This code is not engaged. The reason is that it does not comply
1163 * with recommendations for VIA RNG usage for secure applications
1164 * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
1165 * provide meaningful error control...
1166 */
1167/* Wrapper that provides an interface between the API and
1168 the raw PadLock RNG */
1169static int
1170padlock_rand_bytes(unsigned char *output, int count)
1171{
1172 unsigned int eax, buf;
1173
1174 while (count >= 8) {
1175 eax = padlock_xstore(output, 0);
1176 if (!(eax&(1<<6))) return 0; /* RNG disabled */
1177 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1178 if (eax&(0x1F<<10)) return 0;
1179 if ((eax&0x1F)==0) continue; /* no data, retry... */
1180 if ((eax&0x1F)!=8) return 0; /* fatal failure... */
1181 output += 8;
1182 count -= 8;
1183 }
1184 while (count > 0) {
1185 eax = padlock_xstore(&buf, 3);
1186 if (!(eax&(1<<6))) return 0; /* RNG disabled */
1187 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1188 if (eax&(0x1F<<10)) return 0;
1189 if ((eax&0x1F)==0) continue; /* no data, retry... */
1190 if ((eax&0x1F)!=1) return 0; /* fatal failure... */
1191 *output++ = (unsigned char)buf;
1192 count--;
1193 }
1194 *(volatile unsigned int *)&buf=0;
1195
1196 return 1;
1197}
1198
1199/* Dummy but necessary function */
1200static int
1201padlock_rand_status(void)
1202{
1203 return 1;
1204}
1205
1206/* Prepare structure for registration */
1207static RAND_METHOD padlock_rand = {
1208 NULL, /* seed */
1209 padlock_rand_bytes, /* bytes */
1210 NULL, /* cleanup */
1211 NULL, /* add */
1212 padlock_rand_bytes, /* pseudorand */
1213 padlock_rand_status, /* rand status */
1214};
1215
1216#endif /* COMPILE_HW_PADLOCK */
1217
1218#endif /* !OPENSSL_NO_HW_PADLOCK */
1219#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/eng_pkey.c b/src/lib/libcrypto/engine/eng_pkey.c
index 8c69171511..bc8b21abec 100644
--- a/src/lib/libcrypto/engine/eng_pkey.c
+++ b/src/lib/libcrypto/engine/eng_pkey.c
@@ -53,10 +53,7 @@
53 * 53 *
54 */ 54 */
55 55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h" 56#include "eng_int.h"
59#include <openssl/engine.h>
60 57
61/* Basic get/set stuff */ 58/* Basic get/set stuff */
62 59
diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c
index c69a84a8bf..8879a267d1 100644
--- a/src/lib/libcrypto/engine/eng_table.c
+++ b/src/lib/libcrypto/engine/eng_table.c
@@ -52,49 +52,31 @@
52 * 52 *
53 */ 53 */
54 54
55#include "cryptlib.h"
55#include <openssl/evp.h> 56#include <openssl/evp.h>
56#include <openssl/engine.h> 57#include <openssl/lhash.h>
57#include "eng_int.h" 58#include "eng_int.h"
58 59
59/* This is the type of item in the 'implementation' table. Each 'nid' hashes to
60 * a (potentially NULL) ENGINE_PILE structure which contains a stack of ENGINE*
61 * pointers. These pointers aren't references, because they're inserted and
62 * removed during ENGINE creation and ENGINE destruction. They point to ENGINEs
63 * that *exist* (ie. have a structural reference count greater than zero) rather
64 * than ENGINEs that are *functional*. Each pointer in those stacks are to
65 * ENGINEs that implements the algorithm corresponding to each 'nid'. */
66
67/* The type of the items in the table */ 60/* The type of the items in the table */
68typedef struct st_engine_pile 61typedef struct st_engine_pile
69 { 62 {
70 /* The 'nid' of the algorithm/mode this ENGINE_PILE structure represents 63 /* The 'nid' of this algorithm/mode */
71 * */
72 int nid; 64 int nid;
73 /* A stack of ENGINE pointers for ENGINEs that support this 65 /* ENGINEs that implement this algorithm/mode. */
74 * algorithm/mode. In the event that 'funct' is NULL, the first entry in
75 * this stack that initialises will be set as 'funct' and assumed as the
76 * default for operations of this type. */
77 STACK_OF(ENGINE) *sk; 66 STACK_OF(ENGINE) *sk;
78 /* The default ENGINE to perform this algorithm/mode. */ 67 /* The default ENGINE to perform this algorithm/mode. */
79 ENGINE *funct; 68 ENGINE *funct;
80 /* This value optimises engine_table_select(). If it is called it sets 69 /* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */
81 * this value to 1. Any changes to this ENGINE_PILE resets it to zero.
82 * As such, no ENGINE_init() thrashing is done unless ENGINEs
83 * continually register (and/or unregister). */
84 int uptodate; 70 int uptodate;
85 } ENGINE_PILE; 71 } ENGINE_PILE;
86 72
87/* The type of the hash table of ENGINE_PILE structures such that each are 73/* The type exposed in eng_int.h */
88 * unique and keyed by the 'nid' value. */
89struct st_engine_table 74struct st_engine_table
90 { 75 {
91 LHASH piles; 76 LHASH piles;
92 }; /* ENGINE_TABLE */ 77 }; /* ENGINE_TABLE */
93 78
94/* This value stores global options controlling behaviour of (mostly) the 79/* Global flags (ENGINE_TABLE_FLAG_***). */
95 * engine_table_select() function. It's a bitmask of flag values of the form
96 * ENGINE_TABLE_FLAG_*** (as defined in engine.h) and is controlled by the
97 * ENGINE_[get|set]_table_flags() function. */
98static unsigned int table_flags = 0; 80static unsigned int table_flags = 0;
99 81
100/* API function manipulating 'table_flags' */ 82/* API function manipulating 'table_flags' */
@@ -121,10 +103,8 @@ static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *)
121static int int_table_check(ENGINE_TABLE **t, int create) 103static int int_table_check(ENGINE_TABLE **t, int create)
122 { 104 {
123 LHASH *lh; 105 LHASH *lh;
124 if(*t) 106 if(*t) return 1;
125 return 1; 107 if(!create) return 0;
126 if(!create)
127 return 0;
128 if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), 108 if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash),
129 LHASH_COMP_FN(engine_pile_cmp))) == NULL) 109 LHASH_COMP_FN(engine_pile_cmp))) == NULL)
130 return 0; 110 return 0;
@@ -154,8 +134,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
154 if(!fnd) 134 if(!fnd)
155 { 135 {
156 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); 136 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
157 if(!fnd) 137 if(!fnd) goto end;
158 goto end;
159 fnd->uptodate = 1; 138 fnd->uptodate = 1;
160 fnd->nid = *nids; 139 fnd->nid = *nids;
161 fnd->sk = sk_ENGINE_new_null(); 140 fnd->sk = sk_ENGINE_new_null();
@@ -164,11 +143,11 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
164 OPENSSL_free(fnd); 143 OPENSSL_free(fnd);
165 goto end; 144 goto end;
166 } 145 }
167 fnd->funct= NULL; 146 fnd->funct = NULL;
168 lh_insert(&(*table)->piles, fnd); 147 lh_insert(&(*table)->piles, fnd);
169 } 148 }
170 /* A registration shouldn't add duplciate entries */ 149 /* A registration shouldn't add duplciate entries */
171 sk_ENGINE_delete_ptr(fnd->sk, e); 150 (void)sk_ENGINE_delete_ptr(fnd->sk, e);
172 /* if 'setdefault', this ENGINE goes to the head of the list */ 151 /* if 'setdefault', this ENGINE goes to the head of the list */
173 if(!sk_ENGINE_push(fnd->sk, e)) 152 if(!sk_ENGINE_push(fnd->sk, e))
174 goto end; 153 goto end;
@@ -185,6 +164,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
185 if(fnd->funct) 164 if(fnd->funct)
186 engine_unlocked_finish(fnd->funct, 0); 165 engine_unlocked_finish(fnd->funct, 0);
187 fnd->funct = e; 166 fnd->funct = e;
167 fnd->uptodate = 1;
188 } 168 }
189 nids++; 169 nids++;
190 } 170 }
@@ -199,8 +179,7 @@ static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
199 /* Iterate the 'c->sk' stack removing any occurance of 'e' */ 179 /* Iterate the 'c->sk' stack removing any occurance of 'e' */
200 while((n = sk_ENGINE_find(pile->sk, e)) >= 0) 180 while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
201 { 181 {
202 sk_ENGINE_delete(pile->sk, n); 182 (void)sk_ENGINE_delete(pile->sk, n);
203 /* "touch" this ENGINE_CIPHER */
204 pile->uptodate = 0; 183 pile->uptodate = 0;
205 } 184 }
206 if(pile->funct == e) 185 if(pile->funct == e)
@@ -239,9 +218,7 @@ void engine_table_cleanup(ENGINE_TABLE **table)
239 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 218 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
240 } 219 }
241 220
242/* Exposed API function to get a functional reference from the implementation 221/* return a functional reference for a given 'nid' */
243 * table (ie. try to get a functional reference from the tabled structural
244 * references) for a given cipher 'nid' */
245#ifndef ENGINE_TABLE_DEBUG 222#ifndef ENGINE_TABLE_DEBUG
246ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) 223ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
247#else 224#else
@@ -252,25 +229,21 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in
252 ENGINE_PILE tmplate, *fnd=NULL; 229 ENGINE_PILE tmplate, *fnd=NULL;
253 int initres, loop = 0; 230 int initres, loop = 0;
254 231
255 /* If 'engine_ciphers' is NULL, then it's absolutely *sure* that no
256 * ENGINEs have registered any implementations! */
257 if(!(*table)) 232 if(!(*table))
258 { 233 {
259#ifdef ENGINE_TABLE_DEBUG 234#ifdef ENGINE_TABLE_DEBUG
260 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " 235 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
261 "registered for anything!\n", f, l, nid); 236 "registered!\n", f, l, nid);
262#endif 237#endif
263 return NULL; 238 return NULL;
264 } 239 }
265 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 240 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
266 /* Check again inside the lock otherwise we could race against cleanup 241 /* Check again inside the lock otherwise we could race against cleanup
267 * operations. But don't worry about a fprintf(stderr). */ 242 * operations. But don't worry about a fprintf(stderr). */
268 if(!int_table_check(table, 0)) 243 if(!int_table_check(table, 0)) goto end;
269 goto end;
270 tmplate.nid = nid; 244 tmplate.nid = nid;
271 fnd = lh_retrieve(&(*table)->piles, &tmplate); 245 fnd = lh_retrieve(&(*table)->piles, &tmplate);
272 if(!fnd) 246 if(!fnd) goto end;
273 goto end;
274 if(fnd->funct && engine_unlocked_init(fnd->funct)) 247 if(fnd->funct && engine_unlocked_init(fnd->funct))
275 { 248 {
276#ifdef ENGINE_TABLE_DEBUG 249#ifdef ENGINE_TABLE_DEBUG
@@ -296,34 +269,19 @@ trynext:
296#endif 269#endif
297 goto end; 270 goto end;
298 } 271 }
299#if 0 272 /* Try to initialise the ENGINE? */
300 /* Don't need to get a reference if we hold the lock. If the locking has
301 * to change in future, that would be different ... */
302 ret->struct_ref++; engine_ref_debug(ret, 0, 1)
303#endif
304 /* Try and initialise the ENGINE if it's already functional *or* if the
305 * ENGINE_TABLE_FLAG_NOINIT flag is not set. */
306 if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) 273 if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
307 initres = engine_unlocked_init(ret); 274 initres = engine_unlocked_init(ret);
308 else 275 else
309 initres = 0; 276 initres = 0;
310#if 0
311 /* Release the structural reference */
312 ret->struct_ref--; engine_ref_debug(ret, 0, -1);
313#endif
314 if(initres) 277 if(initres)
315 { 278 {
316 /* If we didn't have a default (functional reference) for this 279 /* Update 'funct' */
317 * 'nid' (or we had one but for whatever reason we're now
318 * initialising a different one), use this opportunity to set
319 * 'funct'. */
320 if((fnd->funct != ret) && engine_unlocked_init(ret)) 280 if((fnd->funct != ret) && engine_unlocked_init(ret))
321 { 281 {
322 /* If there was a previous default we release it. */ 282 /* If there was a previous default we release it. */
323 if(fnd->funct) 283 if(fnd->funct)
324 engine_unlocked_finish(fnd->funct, 0); 284 engine_unlocked_finish(fnd->funct, 0);
325 /* We got an extra functional reference for the
326 * per-'nid' default */
327 fnd->funct = ret; 285 fnd->funct = ret;
328#ifdef ENGINE_TABLE_DEBUG 286#ifdef ENGINE_TABLE_DEBUG
329 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " 287 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
@@ -338,13 +296,9 @@ trynext:
338 } 296 }
339 goto trynext; 297 goto trynext;
340end: 298end:
341 /* Whatever happened - we should "untouch" our uptodate file seeing as 299 /* If it failed, it is unlikely to succeed again until some future
342 * we have tried our best to find a functional reference for 'nid'. If 300 * registrations have taken place. In all cases, we cache. */
343 * it failed, it is unlikely to succeed again until some future 301 if(fnd) fnd->uptodate = 1;
344 * registrations (or unregistrations) have taken place that affect that
345 * 'nid'. */
346 if(fnd)
347 fnd->uptodate = 1;
348#ifdef ENGINE_TABLE_DEBUG 302#ifdef ENGINE_TABLE_DEBUG
349 if(ret) 303 if(ret)
350 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " 304 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h
index 900f75ce8d..3ec59338ff 100644
--- a/src/lib/libcrypto/engine/engine.h
+++ b/src/lib/libcrypto/engine/engine.h
@@ -3,7 +3,7 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -55,6 +55,11 @@
55 * Hudson (tjh@cryptsoft.com). 55 * Hudson (tjh@cryptsoft.com).
56 * 56 *
57 */ 57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
58 63
59#ifndef HEADER_ENGINE_H 64#ifndef HEADER_ENGINE_H
60#define HEADER_ENGINE_H 65#define HEADER_ENGINE_H
@@ -65,7 +70,7 @@
65#error ENGINE is disabled. 70#error ENGINE is disabled.
66#endif 71#endif
67 72
68#include <openssl/ossl_typ.h> 73#ifndef OPENSSL_NO_DEPRECATED
69#include <openssl/bn.h> 74#include <openssl/bn.h>
70#ifndef OPENSSL_NO_RSA 75#ifndef OPENSSL_NO_RSA
71#include <openssl/rsa.h> 76#include <openssl/rsa.h>
@@ -76,34 +81,36 @@
76#ifndef OPENSSL_NO_DH 81#ifndef OPENSSL_NO_DH
77#include <openssl/dh.h> 82#include <openssl/dh.h>
78#endif 83#endif
84#ifndef OPENSSL_NO_ECDH
85#include <openssl/ecdh.h>
86#endif
87#ifndef OPENSSL_NO_ECDSA
88#include <openssl/ecdsa.h>
89#endif
79#include <openssl/rand.h> 90#include <openssl/rand.h>
91#include <openssl/store.h>
80#include <openssl/ui.h> 92#include <openssl/ui.h>
81#include <openssl/symhacks.h>
82#include <openssl/err.h> 93#include <openssl/err.h>
94#endif
95
96#include <openssl/ossl_typ.h>
97#include <openssl/symhacks.h>
83 98
84#ifdef __cplusplus 99#ifdef __cplusplus
85extern "C" { 100extern "C" {
86#endif 101#endif
87 102
88/* Fixups for missing algorithms */
89#ifdef OPENSSL_NO_RSA
90typedef void RSA_METHOD;
91#endif
92#ifdef OPENSSL_NO_DSA
93typedef void DSA_METHOD;
94#endif
95#ifdef OPENSSL_NO_DH
96typedef void DH_METHOD;
97#endif
98
99/* These flags are used to control combinations of algorithm (methods) 103/* These flags are used to control combinations of algorithm (methods)
100 * by bitwise "OR"ing. */ 104 * by bitwise "OR"ing. */
101#define ENGINE_METHOD_RSA (unsigned int)0x0001 105#define ENGINE_METHOD_RSA (unsigned int)0x0001
102#define ENGINE_METHOD_DSA (unsigned int)0x0002 106#define ENGINE_METHOD_DSA (unsigned int)0x0002
103#define ENGINE_METHOD_DH (unsigned int)0x0004 107#define ENGINE_METHOD_DH (unsigned int)0x0004
104#define ENGINE_METHOD_RAND (unsigned int)0x0008 108#define ENGINE_METHOD_RAND (unsigned int)0x0008
109#define ENGINE_METHOD_ECDH (unsigned int)0x0010
110#define ENGINE_METHOD_ECDSA (unsigned int)0x0020
105#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 111#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
106#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 112#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
113#define ENGINE_METHOD_STORE (unsigned int)0x0100
107/* Obvious all-or-nothing cases. */ 114/* Obvious all-or-nothing cases. */
108#define ENGINE_METHOD_ALL (unsigned int)0xFFFF 115#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
109#define ENGINE_METHOD_NONE (unsigned int)0x0000 116#define ENGINE_METHOD_NONE (unsigned int)0x0000
@@ -173,9 +180,15 @@ typedef void DH_METHOD;
173 handles/connections etc. */ 180 handles/connections etc. */
174#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */ 181#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */
175#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used 182#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used
176 when calling the password 183 when calling the password
177 callback and the user 184 callback and the user
178 interface */ 185 interface */
186#define ENGINE_CTRL_LOAD_CONFIGURATION 6 /* Load a configuration, given
187 a string that represents a
188 file name or so */
189#define ENGINE_CTRL_LOAD_SECTION 7 /* Load data from a given
190 section in the already loaded
191 configuration */
179 192
180/* These control commands allow an application to deal with an arbitrary engine 193/* These control commands allow an application to deal with an arbitrary engine
181 * in a dynamic way. Warn: Negative return values indicate errors FOR THESE 194 * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
@@ -222,7 +235,7 @@ typedef void DH_METHOD;
222 235
223/* ENGINE implementations should start the numbering of their own control 236/* ENGINE implementations should start the numbering of their own control
224 * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */ 237 * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
225#define ENGINE_CMD_BASE 200 238#define ENGINE_CMD_BASE 200
226 239
227/* NB: These 2 nCipher "chil" control commands are deprecated, and their 240/* NB: These 2 nCipher "chil" control commands are deprecated, and their
228 * functionality is now available through ENGINE-specific control commands 241 * functionality is now available through ENGINE-specific control commands
@@ -257,11 +270,11 @@ typedef struct ENGINE_CMD_DEFN_st
257 } ENGINE_CMD_DEFN; 270 } ENGINE_CMD_DEFN;
258 271
259/* Generic function pointer */ 272/* Generic function pointer */
260typedef int (*ENGINE_GEN_FUNC_PTR)(); 273typedef int (*ENGINE_GEN_FUNC_PTR)(void);
261/* Generic function pointer taking no arguments */ 274/* Generic function pointer taking no arguments */
262typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *); 275typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
263/* Specific control function pointer */ 276/* Specific control function pointer */
264typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)()); 277typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
265/* Generic load_key function pointer */ 278/* Generic load_key function pointer */
266typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, 279typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
267 UI_METHOD *ui_method, void *callback_data); 280 UI_METHOD *ui_method, void *callback_data);
@@ -305,15 +318,21 @@ ENGINE *ENGINE_by_id(const char *id);
305/* Add all the built-in engines. */ 318/* Add all the built-in engines. */
306void ENGINE_load_openssl(void); 319void ENGINE_load_openssl(void);
307void ENGINE_load_dynamic(void); 320void ENGINE_load_dynamic(void);
308void ENGINE_load_cswift(void); 321#ifndef OPENSSL_NO_STATIC_ENGINE
309void ENGINE_load_chil(void); 322void ENGINE_load_4758cca(void);
323void ENGINE_load_aep(void);
310void ENGINE_load_atalla(void); 324void ENGINE_load_atalla(void);
325void ENGINE_load_chil(void);
326void ENGINE_load_cswift(void);
327#ifndef OPENSSL_NO_GMP
328void ENGINE_load_gmp(void);
329#endif
311void ENGINE_load_nuron(void); 330void ENGINE_load_nuron(void);
312void ENGINE_load_ubsec(void);
313void ENGINE_load_aep(void);
314void ENGINE_load_sureware(void); 331void ENGINE_load_sureware(void);
315void ENGINE_load_4758cca(void); 332void ENGINE_load_ubsec(void);
333#endif
316void ENGINE_load_cryptodev(void); 334void ENGINE_load_cryptodev(void);
335void ENGINE_load_padlock(void);
317void ENGINE_load_builtin_engines(void); 336void ENGINE_load_builtin_engines(void);
318 337
319/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation 338/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
@@ -337,6 +356,14 @@ int ENGINE_register_DSA(ENGINE *e);
337void ENGINE_unregister_DSA(ENGINE *e); 356void ENGINE_unregister_DSA(ENGINE *e);
338void ENGINE_register_all_DSA(void); 357void ENGINE_register_all_DSA(void);
339 358
359int ENGINE_register_ECDH(ENGINE *e);
360void ENGINE_unregister_ECDH(ENGINE *e);
361void ENGINE_register_all_ECDH(void);
362
363int ENGINE_register_ECDSA(ENGINE *e);
364void ENGINE_unregister_ECDSA(ENGINE *e);
365void ENGINE_register_all_ECDSA(void);
366
340int ENGINE_register_DH(ENGINE *e); 367int ENGINE_register_DH(ENGINE *e);
341void ENGINE_unregister_DH(ENGINE *e); 368void ENGINE_unregister_DH(ENGINE *e);
342void ENGINE_register_all_DH(void); 369void ENGINE_register_all_DH(void);
@@ -345,6 +372,10 @@ int ENGINE_register_RAND(ENGINE *e);
345void ENGINE_unregister_RAND(ENGINE *e); 372void ENGINE_unregister_RAND(ENGINE *e);
346void ENGINE_register_all_RAND(void); 373void ENGINE_register_all_RAND(void);
347 374
375int ENGINE_register_STORE(ENGINE *e);
376void ENGINE_unregister_STORE(ENGINE *e);
377void ENGINE_register_all_STORE(void);
378
348int ENGINE_register_ciphers(ENGINE *e); 379int ENGINE_register_ciphers(ENGINE *e);
349void ENGINE_unregister_ciphers(ENGINE *e); 380void ENGINE_unregister_ciphers(ENGINE *e);
350void ENGINE_register_all_ciphers(void); 381void ENGINE_register_all_ciphers(void);
@@ -367,7 +398,7 @@ int ENGINE_register_all_complete(void);
367 * reference to an engine, but many control commands may require the engine be 398 * reference to an engine, but many control commands may require the engine be
368 * functional. The caller should be aware of trying commands that require an 399 * functional. The caller should be aware of trying commands that require an
369 * operational ENGINE, and only use functional references in such situations. */ 400 * operational ENGINE, and only use functional references in such situations. */
370int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 401int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
371 402
372/* This function tests if an ENGINE-specific command is usable as a "setting". 403/* This function tests if an ENGINE-specific command is usable as a "setting".
373 * Eg. in an application's config file that gets processed through 404 * Eg. in an application's config file that gets processed through
@@ -380,7 +411,7 @@ int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
380 * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to 411 * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
381 * use the cmd_name and cmd_optional. */ 412 * use the cmd_name and cmd_optional. */
382int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, 413int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
383 long i, void *p, void (*f)(), int cmd_optional); 414 long i, void *p, void (*f)(void), int cmd_optional);
384 415
385/* This function passes a command-name and argument to an ENGINE. The cmd_name 416/* This function passes a command-name and argument to an ENGINE. The cmd_name
386 * is converted to a command number and the control command is called using 417 * is converted to a command number and the control command is called using
@@ -417,8 +448,11 @@ int ENGINE_set_id(ENGINE *e, const char *id);
417int ENGINE_set_name(ENGINE *e, const char *name); 448int ENGINE_set_name(ENGINE *e, const char *name);
418int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); 449int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
419int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); 450int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
451int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
452int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
420int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); 453int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
421int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); 454int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
455int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
422int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); 456int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
423int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); 457int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
424int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); 458int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
@@ -429,11 +463,11 @@ int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
429int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); 463int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
430int ENGINE_set_flags(ENGINE *e, int flags); 464int ENGINE_set_flags(ENGINE *e, int flags);
431int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); 465int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
432/* These functions (and the "get" function lower down) allow control over any 466/* These functions allow control over any per-structure ENGINE data. */
433 * per-structure ENGINE data. */
434int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 467int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
435 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); 468 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
436int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); 469int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
470void *ENGINE_get_ex_data(const ENGINE *e, int idx);
437 471
438/* This function cleans up anything that needs it. Eg. the ENGINE_add() function 472/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
439 * automatically ensures the list cleanup function is registered to be called 473 * automatically ensures the list cleanup function is registered to be called
@@ -449,8 +483,11 @@ const char *ENGINE_get_id(const ENGINE *e);
449const char *ENGINE_get_name(const ENGINE *e); 483const char *ENGINE_get_name(const ENGINE *e);
450const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); 484const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
451const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); 485const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
486const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
487const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
452const DH_METHOD *ENGINE_get_DH(const ENGINE *e); 488const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
453const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); 489const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
490const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
454ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); 491ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
455ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); 492ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
456ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); 493ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
@@ -463,7 +500,6 @@ const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
463const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); 500const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
464const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); 501const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
465int ENGINE_get_flags(const ENGINE *e); 502int ENGINE_get_flags(const ENGINE *e);
466void *ENGINE_get_ex_data(const ENGINE *e, int idx);
467 503
468/* FUNCTIONAL functions. These functions deal with ENGINE structures 504/* FUNCTIONAL functions. These functions deal with ENGINE structures
469 * that have (or will) be initialised for use. Broadly speaking, the 505 * that have (or will) be initialised for use. Broadly speaking, the
@@ -501,6 +537,8 @@ EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
501ENGINE *ENGINE_get_default_RSA(void); 537ENGINE *ENGINE_get_default_RSA(void);
502/* Same for the other "methods" */ 538/* Same for the other "methods" */
503ENGINE *ENGINE_get_default_DSA(void); 539ENGINE *ENGINE_get_default_DSA(void);
540ENGINE *ENGINE_get_default_ECDH(void);
541ENGINE *ENGINE_get_default_ECDSA(void);
504ENGINE *ENGINE_get_default_DH(void); 542ENGINE *ENGINE_get_default_DH(void);
505ENGINE *ENGINE_get_default_RAND(void); 543ENGINE *ENGINE_get_default_RAND(void);
506/* These functions can be used to get a functional reference to perform 544/* These functions can be used to get a functional reference to perform
@@ -516,6 +554,8 @@ int ENGINE_set_default_RSA(ENGINE *e);
516int ENGINE_set_default_string(ENGINE *e, const char *def_list); 554int ENGINE_set_default_string(ENGINE *e, const char *def_list);
517/* Same for the other "methods" */ 555/* Same for the other "methods" */
518int ENGINE_set_default_DSA(ENGINE *e); 556int ENGINE_set_default_DSA(ENGINE *e);
557int ENGINE_set_default_ECDH(ENGINE *e);
558int ENGINE_set_default_ECDSA(ENGINE *e);
519int ENGINE_set_default_DH(ENGINE *e); 559int ENGINE_set_default_DH(ENGINE *e);
520int ENGINE_set_default_RAND(ENGINE *e); 560int ENGINE_set_default_RAND(ENGINE *e);
521int ENGINE_set_default_ciphers(ENGINE *e); 561int ENGINE_set_default_ciphers(ENGINE *e);
@@ -538,17 +578,20 @@ void ENGINE_add_conf_module(void);
538/**************************/ 578/**************************/
539 579
540/* Binary/behaviour compatibility levels */ 580/* Binary/behaviour compatibility levels */
541#define OSSL_DYNAMIC_VERSION (unsigned long)0x00010200 581#define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000
542/* Binary versions older than this are too old for us (whether we're a loader or 582/* Binary versions older than this are too old for us (whether we're a loader or
543 * a loadee) */ 583 * a loadee) */
544#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00010200 584#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000
545 585
546/* When compiling an ENGINE entirely as an external shared library, loadable by 586/* When compiling an ENGINE entirely as an external shared library, loadable by
547 * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure 587 * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
548 * type provides the calling application's (or library's) error functionality 588 * type provides the calling application's (or library's) error functionality
549 * and memory management function pointers to the loaded library. These should 589 * and memory management function pointers to the loaded library. These should
550 * be used/set in the loaded library code so that the loading application's 590 * be used/set in the loaded library code so that the loading application's
551 * 'state' will be used/changed in all operations. */ 591 * 'state' will be used/changed in all operations. The 'static_state' pointer
592 * allows the loaded library to know if it shares the same static data as the
593 * calling application (or library), and thus whether these callbacks need to be
594 * set or not. */
552typedef void *(*dyn_MEM_malloc_cb)(size_t); 595typedef void *(*dyn_MEM_malloc_cb)(size_t);
553typedef void *(*dyn_MEM_realloc_cb)(void *, size_t); 596typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
554typedef void (*dyn_MEM_free_cb)(void *); 597typedef void (*dyn_MEM_free_cb)(void *);
@@ -576,6 +619,7 @@ typedef struct st_dynamic_LOCK_fns {
576 } dynamic_LOCK_fns; 619 } dynamic_LOCK_fns;
577/* The top-level structure */ 620/* The top-level structure */
578typedef struct st_dynamic_fns { 621typedef struct st_dynamic_fns {
622 void *static_state;
579 const ERR_FNS *err_fns; 623 const ERR_FNS *err_fns;
580 const CRYPTO_EX_DATA_IMPL *ex_data_fns; 624 const CRYPTO_EX_DATA_IMPL *ex_data_fns;
581 dynamic_MEM_fns mem_fns; 625 dynamic_MEM_fns mem_fns;
@@ -593,7 +637,7 @@ typedef struct st_dynamic_fns {
593 * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */ 637 * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
594typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version); 638typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
595#define IMPLEMENT_DYNAMIC_CHECK_FN() \ 639#define IMPLEMENT_DYNAMIC_CHECK_FN() \
596 unsigned long v_check(unsigned long v) { \ 640 OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
597 if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ 641 if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
598 return 0; } 642 return 0; }
599 643
@@ -615,24 +659,35 @@ typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
615typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id, 659typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
616 const dynamic_fns *fns); 660 const dynamic_fns *fns);
617#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ 661#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
662 OPENSSL_EXPORT \
618 int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ 663 int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
619 if (ERR_get_implementation() != fns->err_fns) \ 664 if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
620 { \ 665 if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
621 if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ 666 fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
622 fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ 667 return 0; \
623 return 0; \ 668 CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
624 CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \ 669 CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
625 CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \ 670 CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
626 CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \ 671 CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
627 CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \ 672 CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
628 CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \ 673 if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
629 if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ 674 return 0; \
630 return 0; \ 675 if(!ERR_set_implementation(fns->err_fns)) return 0; \
631 if(!ERR_set_implementation(fns->err_fns)) return 0; \ 676 skip_cbs: \
632 } \
633 if(!fn(e,id)) return 0; \ 677 if(!fn(e,id)) return 0; \
634 return 1; } 678 return 1; }
635 679
680/* If the loading application (or library) and the loaded ENGINE library share
681 * the same static data (eg. they're both dynamically linked to the same
682 * libcrypto.so) we need a way to avoid trying to set system callbacks - this
683 * would fail, and for the same reason that it's unnecessary to try. If the
684 * loaded ENGINE has (or gets from through the loader) its own copy of the
685 * libcrypto static data, we will need to set the callbacks. The easiest way to
686 * detect this is to have a function that returns a pointer to some static data
687 * and let the loading application and loaded ENGINE compare their respective
688 * values. */
689void *ENGINE_get_static_state(void);
690
636#if defined(__OpenBSD__) || defined(__FreeBSD__) 691#if defined(__OpenBSD__) || defined(__FreeBSD__)
637void ENGINE_setup_bsd_cryptodev(void); 692void ENGINE_setup_bsd_cryptodev(void);
638#endif 693#endif
@@ -649,6 +704,7 @@ void ERR_load_ENGINE_strings(void);
649#define ENGINE_F_DYNAMIC_CTRL 180 704#define ENGINE_F_DYNAMIC_CTRL 180
650#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 705#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
651#define ENGINE_F_DYNAMIC_LOAD 182 706#define ENGINE_F_DYNAMIC_LOAD 182
707#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183
652#define ENGINE_F_ENGINE_ADD 105 708#define ENGINE_F_ENGINE_ADD 105
653#define ENGINE_F_ENGINE_BY_ID 106 709#define ENGINE_F_ENGINE_BY_ID 106
654#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 710#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
@@ -656,7 +712,7 @@ void ERR_load_ENGINE_strings(void);
656#define ENGINE_F_ENGINE_CTRL_CMD 178 712#define ENGINE_F_ENGINE_CTRL_CMD 178
657#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 713#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
658#define ENGINE_F_ENGINE_FINISH 107 714#define ENGINE_F_ENGINE_FINISH 107
659#define ENGINE_F_ENGINE_FREE 108 715#define ENGINE_F_ENGINE_FREE_UTIL 108
660#define ENGINE_F_ENGINE_GET_CIPHER 185 716#define ENGINE_F_ENGINE_GET_CIPHER 185
661#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 717#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
662#define ENGINE_F_ENGINE_GET_DIGEST 186 718#define ENGINE_F_ENGINE_GET_DIGEST 186
@@ -667,7 +723,6 @@ void ERR_load_ENGINE_strings(void);
667#define ENGINE_F_ENGINE_LIST_REMOVE 121 723#define ENGINE_F_ENGINE_LIST_REMOVE 121
668#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 724#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
669#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 725#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
670#define ENGINE_F_ENGINE_MODULE_INIT 187
671#define ENGINE_F_ENGINE_NEW 122 726#define ENGINE_F_ENGINE_NEW 122
672#define ENGINE_F_ENGINE_REMOVE 123 727#define ENGINE_F_ENGINE_REMOVE 123
673#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 728#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
@@ -676,11 +731,12 @@ void ERR_load_ENGINE_strings(void);
676#define ENGINE_F_ENGINE_SET_NAME 130 731#define ENGINE_F_ENGINE_SET_NAME 130
677#define ENGINE_F_ENGINE_TABLE_REGISTER 184 732#define ENGINE_F_ENGINE_TABLE_REGISTER 184
678#define ENGINE_F_ENGINE_UNLOAD_KEY 152 733#define ENGINE_F_ENGINE_UNLOAD_KEY 152
734#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191
679#define ENGINE_F_ENGINE_UP_REF 190 735#define ENGINE_F_ENGINE_UP_REF 190
680#define ENGINE_F_INT_CTRL_HELPER 172 736#define ENGINE_F_INT_CTRL_HELPER 172
681#define ENGINE_F_INT_ENGINE_CONFIGURE 188 737#define ENGINE_F_INT_ENGINE_CONFIGURE 188
738#define ENGINE_F_INT_ENGINE_MODULE_INIT 187
682#define ENGINE_F_LOG_MESSAGE 141 739#define ENGINE_F_LOG_MESSAGE 141
683#define ENGINE_F_SET_DATA_CTX 183
684 740
685/* Reason codes. */ 741/* Reason codes. */
686#define ENGINE_R_ALREADY_LOADED 100 742#define ENGINE_R_ALREADY_LOADED 100
diff --git a/src/lib/libcrypto/engine/tb_cipher.c b/src/lib/libcrypto/engine/tb_cipher.c
index 50b3cec1fa..177fc1fb73 100644
--- a/src/lib/libcrypto/engine/tb_cipher.c
+++ b/src/lib/libcrypto/engine/tb_cipher.c
@@ -52,8 +52,6 @@
52 * 52 *
53 */ 53 */
54 54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h" 55#include "eng_int.h"
58 56
59/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that 57/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that
diff --git a/src/lib/libcrypto/engine/tb_dh.c b/src/lib/libcrypto/engine/tb_dh.c
index e290e1702b..6e9d428761 100644
--- a/src/lib/libcrypto/engine/tb_dh.c
+++ b/src/lib/libcrypto/engine/tb_dh.c
@@ -52,8 +52,6 @@
52 * 52 *
53 */ 53 */
54 54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h" 55#include "eng_int.h"
58 56
59/* If this symbol is defined then ENGINE_get_default_DH(), the function that is 57/* If this symbol is defined then ENGINE_get_default_DH(), the function that is
diff --git a/src/lib/libcrypto/engine/tb_digest.c b/src/lib/libcrypto/engine/tb_digest.c
index e82d2a17c9..d3f4bb2747 100644
--- a/src/lib/libcrypto/engine/tb_digest.c
+++ b/src/lib/libcrypto/engine/tb_digest.c
@@ -52,8 +52,6 @@
52 * 52 *
53 */ 53 */
54 54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h" 55#include "eng_int.h"
58 56
59/* If this symbol is defined then ENGINE_get_digest_engine(), the function that 57/* If this symbol is defined then ENGINE_get_digest_engine(), the function that
diff --git a/src/lib/libcrypto/engine/tb_dsa.c b/src/lib/libcrypto/engine/tb_dsa.c
index 7efe181927..e4674f5f07 100644
--- a/src/lib/libcrypto/engine/tb_dsa.c
+++ b/src/lib/libcrypto/engine/tb_dsa.c
@@ -52,8 +52,6 @@
52 * 52 *
53 */ 53 */
54 54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h" 55#include "eng_int.h"
58 56
59/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is 57/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is
diff --git a/src/lib/libcrypto/engine/tb_ecdh.c b/src/lib/libcrypto/engine/tb_ecdh.c
new file mode 100644
index 0000000000..c8ec7812c5
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_ecdh.c
@@ -0,0 +1,133 @@
1/* crypto/engine/tb_ecdh.c */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The ECDH engine software is originally written by Nils Gura and
13 * Douglas Stebila of Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * licensing@OpenSSL.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
67 *
68 */
69
70#include "eng_int.h"
71
72/* If this symbol is defined then ENGINE_get_default_ECDH(), the function that is
73 * used by ECDH to hook in implementation code and cache defaults (etc), will
74 * display brief debugging summaries to stderr with the 'nid'. */
75/* #define ENGINE_ECDH_DEBUG */
76
77static ENGINE_TABLE *ecdh_table = NULL;
78static const int dummy_nid = 1;
79
80void ENGINE_unregister_ECDH(ENGINE *e)
81 {
82 engine_table_unregister(&ecdh_table, e);
83 }
84
85static void engine_unregister_all_ECDH(void)
86 {
87 engine_table_cleanup(&ecdh_table);
88 }
89
90int ENGINE_register_ECDH(ENGINE *e)
91 {
92 if(e->ecdh_meth)
93 return engine_table_register(&ecdh_table,
94 engine_unregister_all_ECDH, e, &dummy_nid, 1, 0);
95 return 1;
96 }
97
98void ENGINE_register_all_ECDH()
99 {
100 ENGINE *e;
101
102 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
103 ENGINE_register_ECDH(e);
104 }
105
106int ENGINE_set_default_ECDH(ENGINE *e)
107 {
108 if(e->ecdh_meth)
109 return engine_table_register(&ecdh_table,
110 engine_unregister_all_ECDH, e, &dummy_nid, 1, 1);
111 return 1;
112 }
113
114/* Exposed API function to get a functional reference from the implementation
115 * table (ie. try to get a functional reference from the tabled structural
116 * references). */
117ENGINE *ENGINE_get_default_ECDH(void)
118 {
119 return engine_table_select(&ecdh_table, dummy_nid);
120 }
121
122/* Obtains an ECDH implementation from an ENGINE functional reference */
123const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e)
124 {
125 return e->ecdh_meth;
126 }
127
128/* Sets an ECDH implementation in an ENGINE structure */
129int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth)
130 {
131 e->ecdh_meth = ecdh_meth;
132 return 1;
133 }
diff --git a/src/lib/libcrypto/engine/tb_ecdsa.c b/src/lib/libcrypto/engine/tb_ecdsa.c
new file mode 100644
index 0000000000..005ecb622c
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_ecdsa.c
@@ -0,0 +1,118 @@
1/* ====================================================================
2 * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_default_ECDSA(), the function that is
58 * used by ECDSA to hook in implementation code and cache defaults (etc), will
59 * display brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_ECDSA_DEBUG */
61
62static ENGINE_TABLE *ecdsa_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_ECDSA(ENGINE *e)
66 {
67 engine_table_unregister(&ecdsa_table, e);
68 }
69
70static void engine_unregister_all_ECDSA(void)
71 {
72 engine_table_cleanup(&ecdsa_table);
73 }
74
75int ENGINE_register_ECDSA(ENGINE *e)
76 {
77 if(e->ecdsa_meth)
78 return engine_table_register(&ecdsa_table,
79 engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_ECDSA()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_ECDSA(e);
89 }
90
91int ENGINE_set_default_ECDSA(ENGINE *e)
92 {
93 if(e->ecdsa_meth)
94 return engine_table_register(&ecdsa_table,
95 engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1);
96 return 1;
97 }
98
99/* Exposed API function to get a functional reference from the implementation
100 * table (ie. try to get a functional reference from the tabled structural
101 * references). */
102ENGINE *ENGINE_get_default_ECDSA(void)
103 {
104 return engine_table_select(&ecdsa_table, dummy_nid);
105 }
106
107/* Obtains an ECDSA implementation from an ENGINE functional reference */
108const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e)
109 {
110 return e->ecdsa_meth;
111 }
112
113/* Sets an ECDSA implementation in an ENGINE structure */
114int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth)
115 {
116 e->ecdsa_meth = ecdsa_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_rand.c b/src/lib/libcrypto/engine/tb_rand.c
index 69b67111bc..f36f67c0f6 100644
--- a/src/lib/libcrypto/engine/tb_rand.c
+++ b/src/lib/libcrypto/engine/tb_rand.c
@@ -52,8 +52,6 @@
52 * 52 *
53 */ 53 */
54 54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h" 55#include "eng_int.h"
58 56
59/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is 57/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is
diff --git a/src/lib/libcrypto/engine/tb_rsa.c b/src/lib/libcrypto/engine/tb_rsa.c
index fee4867f52..fbc707fd26 100644
--- a/src/lib/libcrypto/engine/tb_rsa.c
+++ b/src/lib/libcrypto/engine/tb_rsa.c
@@ -52,8 +52,6 @@
52 * 52 *
53 */ 53 */
54 54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h" 55#include "eng_int.h"
58 56
59/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is 57/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is
diff --git a/src/lib/libcrypto/engine/tb_store.c b/src/lib/libcrypto/engine/tb_store.c
new file mode 100644
index 0000000000..8cc435c935
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_store.c
@@ -0,0 +1,123 @@
1/* ====================================================================
2 * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_default_STORE(), the function that is
58 * used by STORE to hook in implementation code and cache defaults (etc), will
59 * display brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_STORE_DEBUG */
61
62static ENGINE_TABLE *store_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_STORE(ENGINE *e)
66 {
67 engine_table_unregister(&store_table, e);
68 }
69
70static void engine_unregister_all_STORE(void)
71 {
72 engine_table_cleanup(&store_table);
73 }
74
75int ENGINE_register_STORE(ENGINE *e)
76 {
77 if(e->store_meth)
78 return engine_table_register(&store_table,
79 engine_unregister_all_STORE, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_STORE()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_STORE(e);
89 }
90
91/* The following two functions are removed because they're useless. */
92#if 0
93int ENGINE_set_default_STORE(ENGINE *e)
94 {
95 if(e->store_meth)
96 return engine_table_register(&store_table,
97 engine_unregister_all_STORE, e, &dummy_nid, 1, 1);
98 return 1;
99 }
100#endif
101
102#if 0
103/* Exposed API function to get a functional reference from the implementation
104 * table (ie. try to get a functional reference from the tabled structural
105 * references). */
106ENGINE *ENGINE_get_default_STORE(void)
107 {
108 return engine_table_select(&store_table, dummy_nid);
109 }
110#endif
111
112/* Obtains an STORE implementation from an ENGINE functional reference */
113const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e)
114 {
115 return e->store_meth;
116 }
117
118/* Sets an STORE implementation in an ENGINE structure */
119int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth)
120 {
121 e->store_meth = store_meth;
122 return 1;
123 }