1 | ENGINE
|
---|
2 | ======
|
---|
3 |
|
---|
4 | With OpenSSL 0.9.6, a new component was added to support alternative
|
---|
5 | cryptography implementations, most commonly for interfacing with external
|
---|
6 | crypto devices (eg. accelerator cards). This component is called ENGINE,
|
---|
7 | and its presence in OpenSSL 0.9.6 (and subsequent bug-fix releases)
|
---|
8 | caused a little confusion as 0.9.6** releases were rolled in two
|
---|
9 | versions, a "standard" and an "engine" version. In development for 0.9.7,
|
---|
10 | the ENGINE code has been merged into the main branch and will be present
|
---|
11 | in the standard releases from 0.9.7 forwards.
|
---|
12 |
|
---|
13 | There are currently built-in ENGINE implementations for the following
|
---|
14 | crypto devices:
|
---|
15 |
|
---|
16 | o Microsoft CryptoAPI
|
---|
17 | o VIA Padlock
|
---|
18 | o nCipher CHIL
|
---|
19 |
|
---|
20 | In addition, dynamic binding to external ENGINE implementations is now
|
---|
21 | provided by a special ENGINE called "dynamic". See the "DYNAMIC ENGINE"
|
---|
22 | section below for details.
|
---|
23 |
|
---|
24 | At this stage, a number of things are still needed and are being worked on:
|
---|
25 |
|
---|
26 | 1 Integration of EVP support.
|
---|
27 | 2 Configuration support.
|
---|
28 | 3 Documentation!
|
---|
29 |
|
---|
30 | 1 With respect to EVP, this relates to support for ciphers and digests in
|
---|
31 | the ENGINE model so that alternative implementations of existing
|
---|
32 | algorithms/modes (or previously unimplemented ones) can be provided by
|
---|
33 | ENGINE implementations.
|
---|
34 |
|
---|
35 | 2 Configuration support currently exists in the ENGINE API itself, in the
|
---|
36 | form of "control commands". These allow an application to expose to the
|
---|
37 | user/admin the set of commands and parameter types a given ENGINE
|
---|
38 | implementation supports, and for an application to directly feed string
|
---|
39 | based input to those ENGINEs, in the form of name-value pairs. This is an
|
---|
40 | extensible way for ENGINEs to define their own "configuration" mechanisms
|
---|
41 | that are specific to a given ENGINE (eg. for a particular hardware
|
---|
42 | device) but that should be consistent across *all* OpenSSL-based
|
---|
43 | applications when they use that ENGINE. Work is in progress (or at least
|
---|
44 | in planning) for supporting these control commands from the CONF (or
|
---|
45 | NCONF) code so that applications using OpenSSL's existing configuration
|
---|
46 | file format can have ENGINE settings specified in much the same way.
|
---|
47 | Presently however, applications must use the ENGINE API itself to provide
|
---|
48 | such functionality. To see first hand the types of commands available
|
---|
49 | with the various compiled-in ENGINEs (see further down for dynamic
|
---|
50 | ENGINEs), use the "engine" openssl utility with full verbosity, ie;
|
---|
51 | openssl engine -vvvv
|
---|
52 |
|
---|
53 | 3 Documentation? Volunteers welcome! The source code is reasonably well
|
---|
54 | self-documenting, but some summaries and usage instructions are needed -
|
---|
55 | moreover, they are needed in the same POD format the existing OpenSSL
|
---|
56 | documentation is provided in. Any complete or incomplete contributions
|
---|
57 | would help make this happen.
|
---|
58 |
|
---|
59 | STABILITY & BUG-REPORTS
|
---|
60 | =======================
|
---|
61 |
|
---|
62 | What already exists is fairly stable as far as it has been tested, but
|
---|
63 | the test base has been a bit small most of the time. For the most part,
|
---|
64 | the vendors of the devices these ENGINEs support have contributed to the
|
---|
65 | development and/or testing of the implementations, and *usually* (with no
|
---|
66 | guarantees) have experience in using the ENGINE support to drive their
|
---|
67 | devices from common OpenSSL-based applications. Bugs and/or inexplicable
|
---|
68 | behaviour in using a specific ENGINE implementation should be sent to the
|
---|
69 | author of that implementation (if it is mentioned in the corresponding C
|
---|
70 | file), and in the case of implementations for commercial hardware
|
---|
71 | devices, also through whatever vendor support channels are available. If
|
---|
72 | none of this is possible, or the problem seems to be something about the
|
---|
73 | ENGINE API itself (ie. not necessarily specific to a particular ENGINE
|
---|
74 | implementation) then you should mail complete details to the relevant
|
---|
75 | OpenSSL mailing list. For a definition of "complete details", refer to
|
---|
76 | the OpenSSL "README" file. As for which list to send it to;
|
---|
77 |
|
---|
78 | openssl-users: if you are *using* the ENGINE abstraction, either in an
|
---|
79 | pre-compiled application or in your own application code.
|
---|
80 |
|
---|
81 | openssl-dev: if you are discussing problems with OpenSSL source code.
|
---|
82 |
|
---|
83 | USAGE
|
---|
84 | =====
|
---|
85 |
|
---|
86 | The default "openssl" ENGINE is always chosen when performing crypto
|
---|
87 | operations unless you specify otherwise. You must actively tell the
|
---|
88 | openssl utility commands to use anything else through a new command line
|
---|
89 | switch called "-engine". Also, if you want to use the ENGINE support in
|
---|
90 | your own code to do something similar, you must likewise explicitly
|
---|
91 | select the ENGINE implementation you want.
|
---|
92 |
|
---|
93 | Depending on the type of hardware, system, and configuration, "settings"
|
---|
94 | may need to be applied to an ENGINE for it to function as expected/hoped.
|
---|
95 | The recommended way of doing this is for the application to support
|
---|
96 | ENGINE "control commands" so that each ENGINE implementation can provide
|
---|
97 | whatever configuration primitives it might require and the application
|
---|
98 | can allow the user/admin (and thus the hardware vendor's support desk
|
---|
99 | also) to provide any such input directly to the ENGINE implementation.
|
---|
100 | This way, applications do not need to know anything specific to any
|
---|
101 | device, they only need to provide the means to carry such user/admin
|
---|
102 | input through to the ENGINE in question. Ie. this connects *you* (and
|
---|
103 | your helpdesk) to the specific ENGINE implementation (and device), and
|
---|
104 | allows application authors to not get buried in hassle supporting
|
---|
105 | arbitrary devices they know (and care) nothing about.
|
---|
106 |
|
---|
107 | A new "openssl" utility, "openssl engine", has been added in that allows
|
---|
108 | for testing and examination of ENGINE implementations. Basic usage
|
---|
109 | instructions are available by specifying the "-?" command line switch.
|
---|
110 |
|
---|
111 | DYNAMIC ENGINES
|
---|
112 | ===============
|
---|
113 |
|
---|
114 | The new "dynamic" ENGINE provides a low-overhead way to support ENGINE
|
---|
115 | implementations that aren't pre-compiled and linked into OpenSSL-based
|
---|
116 | applications. This could be because existing compiled-in implementations
|
---|
117 | have known problems and you wish to use a newer version with an existing
|
---|
118 | application. It could equally be because the application (or OpenSSL
|
---|
119 | library) you are using simply doesn't have support for the ENGINE you
|
---|
120 | wish to use, and the ENGINE provider (eg. hardware vendor) is providing
|
---|
121 | you with a self-contained implementation in the form of a shared-library.
|
---|
122 | The other use-case for "dynamic" is with applications that wish to
|
---|
123 | maintain the smallest foot-print possible and so do not link in various
|
---|
124 | ENGINE implementations from OpenSSL, but instead leaves you to provide
|
---|
125 | them, if you want them, in the form of "dynamic"-loadable
|
---|
126 | shared-libraries. It should be possible for hardware vendors to provide
|
---|
127 | their own shared-libraries to support arbitrary hardware to work with
|
---|
128 | applications based on OpenSSL 0.9.7 or later. If you're using an
|
---|
129 | application based on 0.9.7 (or later) and the support you desire is only
|
---|
130 | announced for versions later than the one you need, ask the vendor to
|
---|
131 | backport their ENGINE to the version you need.
|
---|
132 |
|
---|
133 | How does "dynamic" work?
|
---|
134 | ------------------------
|
---|
135 | The dynamic ENGINE has a special flag in its implementation such that
|
---|
136 | every time application code asks for the 'dynamic' ENGINE, it in fact
|
---|
137 | gets its own copy of it. As such, multi-threaded code (or code that
|
---|
138 | multiplexes multiple uses of 'dynamic' in a single application in any
|
---|
139 | way at all) does not get confused by 'dynamic' being used to do many
|
---|
140 | independent things. Other ENGINEs typically don't do this so there is
|
---|
141 | only ever 1 ENGINE structure of its type (and reference counts are used
|
---|
142 | to keep order). The dynamic ENGINE itself provides absolutely no
|
---|
143 | cryptographic functionality, and any attempt to "initialise" the ENGINE
|
---|
144 | automatically fails. All it does provide are a few "control commands"
|
---|
145 | that can be used to control how it will load an external ENGINE
|
---|
146 | implementation from a shared-library. To see these control commands,
|
---|
147 | use the command-line;
|
---|
148 |
|
---|
149 | openssl engine -vvvv dynamic
|
---|
150 |
|
---|
151 | The "SO_PATH" control command should be used to identify the
|
---|
152 | shared-library that contains the ENGINE implementation, and "NO_VCHECK"
|
---|
153 | might possibly be useful if there is a minor version conflict and you
|
---|
154 | (or a vendor helpdesk) is convinced you can safely ignore it.
|
---|
155 | "ID" is probably only needed if a shared-library implements
|
---|
156 | multiple ENGINEs, but if you know the engine id you expect to be using,
|
---|
157 | it doesn't hurt to specify it (and this provides a sanity check if
|
---|
158 | nothing else). "LIST_ADD" is only required if you actually wish the
|
---|
159 | loaded ENGINE to be discoverable by application code later on using the
|
---|
160 | ENGINE's "id". For most applications, this isn't necessary - but some
|
---|
161 | application authors may have nifty reasons for using it. The "LOAD"
|
---|
162 | command is the only one that takes no parameters and is the command
|
---|
163 | that uses the settings from any previous commands to actually *load*
|
---|
164 | the shared-library ENGINE implementation. If this command succeeds, the
|
---|
165 | (copy of the) 'dynamic' ENGINE will magically morph into the ENGINE
|
---|
166 | that has been loaded from the shared-library. As such, any control
|
---|
167 | commands supported by the loaded ENGINE could then be executed as per
|
---|
168 | normal. Eg. if ENGINE "foo" is implemented in the shared-library
|
---|
169 | "libfoo.so" and it supports some special control command "CMD_FOO", the
|
---|
170 | following code would load and use it (NB: obviously this code has no
|
---|
171 | error checking);
|
---|
172 |
|
---|
173 | ENGINE *e = ENGINE_by_id("dynamic");
|
---|
174 | ENGINE_ctrl_cmd_string(e, "SO_PATH", "/lib/libfoo.so", 0);
|
---|
175 | ENGINE_ctrl_cmd_string(e, "ID", "foo", 0);
|
---|
176 | ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0);
|
---|
177 | ENGINE_ctrl_cmd_string(e, "CMD_FOO", "some input data", 0);
|
---|
178 |
|
---|
179 | For testing, the "openssl engine" utility can be useful for this sort
|
---|
180 | of thing. For example the above code excerpt would achieve much the
|
---|
181 | same result as;
|
---|
182 |
|
---|
183 | openssl engine dynamic \
|
---|
184 | -pre SO_PATH:/lib/libfoo.so \
|
---|
185 | -pre ID:foo \
|
---|
186 | -pre LOAD \
|
---|
187 | -pre "CMD_FOO:some input data"
|
---|
188 |
|
---|
189 | Or to simply see the list of commands supported by the "foo" ENGINE;
|
---|
190 |
|
---|
191 | openssl engine -vvvv dynamic \
|
---|
192 | -pre SO_PATH:/lib/libfoo.so \
|
---|
193 | -pre ID:foo \
|
---|
194 | -pre LOAD
|
---|
195 |
|
---|
196 | Applications that support the ENGINE API and more specifically, the
|
---|
197 | "control commands" mechanism, will provide some way for you to pass
|
---|
198 | such commands through to ENGINEs. As such, you would select "dynamic"
|
---|
199 | as the ENGINE to use, and the parameters/commands you pass would
|
---|
200 | control the *actual* ENGINE used. Each command is actually a name-value
|
---|
201 | pair and the value can sometimes be omitted (eg. the "LOAD" command).
|
---|
202 | Whilst the syntax demonstrated in "openssl engine" uses a colon to
|
---|
203 | separate the command name from the value, applications may provide
|
---|
204 | their own syntax for making that separation (eg. a win32 registry
|
---|
205 | key-value pair may be used by some applications). The reason for the
|
---|
206 | "-pre" syntax in the "openssl engine" utility is that some commands
|
---|
207 | might be issued to an ENGINE *after* it has been initialised for use.
|
---|
208 | Eg. if an ENGINE implementation requires a smart-card to be inserted
|
---|
209 | during initialisation (or a PIN to be typed, or whatever), there may be
|
---|
210 | a control command you can issue afterwards to "forget" the smart-card
|
---|
211 | so that additional initialisation is no longer possible. In
|
---|
212 | applications such as web-servers, where potentially volatile code may
|
---|
213 | run on the same host system, this may provide some arguable security
|
---|
214 | value. In such a case, the command would be passed to the ENGINE after
|
---|
215 | it has been initialised for use, and so the "-post" switch would be
|
---|
216 | used instead. Applications may provide a different syntax for
|
---|
217 | supporting this distinction, and some may simply not provide it at all
|
---|
218 | ("-pre" is almost always what you're after, in reality).
|
---|
219 |
|
---|
220 | How do I build a "dynamic" ENGINE?
|
---|
221 | ----------------------------------
|
---|
222 | This question is trickier - currently OpenSSL bundles various ENGINE
|
---|
223 | implementations that are statically built in, and any application that
|
---|
224 | calls the "ENGINE_load_builtin_engines()" function will automatically
|
---|
225 | have all such ENGINEs available (and occupying memory). Applications
|
---|
226 | that don't call that function have no ENGINEs available like that and
|
---|
227 | would have to use "dynamic" to load any such ENGINE - but on the other
|
---|
228 | hand such applications would only have the memory footprint of any
|
---|
229 | ENGINEs explicitly loaded using user/admin provided control commands.
|
---|
230 | The main advantage of not statically linking ENGINEs and only using
|
---|
231 | "dynamic" for hardware support is that any installation using no
|
---|
232 | "external" ENGINE suffers no unnecessary memory footprint from unused
|
---|
233 | ENGINEs. Likewise, installations that do require an ENGINE incur the
|
---|
234 | overheads from only *that* ENGINE once it has been loaded.
|
---|
235 |
|
---|
236 | Sounds good? Maybe, but currently building an ENGINE implementation as
|
---|
237 | a shared-library that can be loaded by "dynamic" isn't automated in
|
---|
238 | OpenSSL's build process. It can be done manually quite easily however.
|
---|
239 | Such a shared-library can either be built with any OpenSSL code it
|
---|
240 | needs statically linked in, or it can link dynamically against OpenSSL
|
---|
241 | if OpenSSL itself is built as a shared library. The instructions are
|
---|
242 | the same in each case, but in the former (statically linked any
|
---|
243 | dependencies on OpenSSL) you must ensure OpenSSL is built with
|
---|
244 | position-independent code ("PIC"). The default OpenSSL compilation may
|
---|
245 | already specify the relevant flags to do this, but you should consult
|
---|
246 | with your compiler documentation if you are in any doubt.
|
---|
247 |
|
---|
248 | This example will show building the "atalla" ENGINE in the
|
---|
249 | crypto/engine/ directory as a shared-library for use via the "dynamic"
|
---|
250 | ENGINE.
|
---|
251 | 1) "cd" to the crypto/engine/ directory of a pre-compiled OpenSSL
|
---|
252 | source tree.
|
---|
253 | 2) Recompile at least one source file so you can see all the compiler
|
---|
254 | flags (and syntax) being used to build normally. Eg;
|
---|
255 | touch hw_atalla.c ; make
|
---|
256 | will rebuild "hw_atalla.o" using all such flags.
|
---|
257 | 3) Manually enter the same compilation line to compile the
|
---|
258 | "hw_atalla.c" file but with the following two changes;
|
---|
259 | (a) add "-DENGINE_DYNAMIC_SUPPORT" to the command line switches,
|
---|
260 | (b) change the output file from "hw_atalla.o" to something new,
|
---|
261 | eg. "tmp_atalla.o"
|
---|
262 | 4) Link "tmp_atalla.o" into a shared-library using the top-level
|
---|
263 | OpenSSL libraries to resolve any dependencies. The syntax for doing
|
---|
264 | this depends heavily on your system/compiler and is a nightmare
|
---|
265 | known well to anyone who has worked with shared-library portability
|
---|
266 | before. 'gcc' on Linux, for example, would use the following syntax;
|
---|
267 | gcc -shared -o dyn_atalla.so tmp_atalla.o -L../.. -lcrypto
|
---|
268 | 5) Test your shared library using "openssl engine" as explained in the
|
---|
269 | previous section. Eg. from the top-level directory, you might try;
|
---|
270 | apps/openssl engine -vvvv dynamic \
|
---|
271 | -pre SO_PATH:./crypto/engine/dyn_atalla.so -pre LOAD
|
---|
272 | If the shared-library loads successfully, you will see both "-pre"
|
---|
273 | commands marked as "SUCCESS" and the list of control commands
|
---|
274 | displayed (because of "-vvvv") will be the control commands for the
|
---|
275 | *atalla* ENGINE (ie. *not* the 'dynamic' ENGINE). You can also add
|
---|
276 | the "-t" switch to the utility if you want it to try and initialise
|
---|
277 | the atalla ENGINE for use to test any possible hardware/driver
|
---|
278 | issues.
|
---|
279 |
|
---|
280 | PROBLEMS
|
---|
281 | ========
|
---|
282 |
|
---|
283 | It seems like the ENGINE part doesn't work too well with CryptoSwift on Win32.
|
---|
284 | A quick test done right before the release showed that trying "openssl speed
|
---|
285 | -engine cswift" generated errors. If the DSO gets enabled, an attempt is made
|
---|
286 | to write at memory address 0x00000002.
|
---|
287 |
|
---|