diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/engine/README | 211 |
1 files changed, 0 insertions, 211 deletions
diff --git a/src/lib/libcrypto/engine/README b/src/lib/libcrypto/engine/README deleted file mode 100644 index 6b69b70f57..0000000000 --- a/src/lib/libcrypto/engine/README +++ /dev/null | |||
| @@ -1,211 +0,0 @@ | |||
| 1 | Notes: 2001-09-24 | ||
| 2 | ----------------- | ||
| 3 | |||
| 4 | This "description" (if one chooses to call it that) needed some major updating | ||
| 5 | so here goes. This update addresses a change being made at the same time to | ||
| 6 | OpenSSL, and it pretty much completely restructures the underlying mechanics of | ||
| 7 | the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals | ||
| 8 | for masochists" document *and* a rather extensive commit log message. (I'd get | ||
| 9 | lynched for sticking all this in CHANGES or the commit mails :-). | ||
| 10 | |||
| 11 | ENGINE_TABLE underlies this restructuring, as described in the internal header | ||
| 12 | "eng_int.h", implemented in eng_table.c, and used in each of the "class" files; | ||
| 13 | tb_rsa.c, tb_dsa.c, etc. | ||
| 14 | |||
| 15 | However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so | ||
| 16 | I'll mention a bit about that first. EVP_CIPHER (and most of this applies | ||
| 17 | equally to EVP_MD for digests) is both a "method" and a algorithm/mode | ||
| 18 | identifier that, in the current API, "lingers". These cipher description + | ||
| 19 | implementation structures can be defined or obtained directly by applications, | ||
| 20 | or can be loaded "en masse" into EVP storage so that they can be catalogued and | ||
| 21 | searched in various ways, ie. two ways of encrypting with the "des_cbc" | ||
| 22 | algorithm/mode pair are; | ||
| 23 | |||
| 24 | (i) directly; | ||
| 25 | const EVP_CIPHER *cipher = EVP_des_cbc(); | ||
| 26 | EVP_EncryptInit(&ctx, cipher, key, iv); | ||
| 27 | [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...] | ||
| 28 | |||
| 29 | (ii) indirectly; | ||
| 30 | OpenSSL_add_all_ciphers(); | ||
| 31 | cipher = EVP_get_cipherbyname("des_cbc"); | ||
| 32 | EVP_EncryptInit(&ctx, cipher, key, iv); | ||
| 33 | [ ... etc ... ] | ||
| 34 | |||
| 35 | The latter is more generally used because it also allows ciphers/digests to be | ||
| 36 | looked up based on other identifiers which can be useful for automatic cipher | ||
| 37 | selection, eg. in SSL/TLS, or by user-controllable configuration. | ||
| 38 | |||
| 39 | The important point about this is that EVP_CIPHER definitions and structures are | ||
| 40 | passed around with impunity and there is no safe way, without requiring massive | ||
| 41 | rewrites of many applications, to assume that EVP_CIPHERs can be reference | ||
| 42 | counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it | ||
| 43 | comes from can "safely" be destroyed. Unless of course the way of getting to | ||
| 44 | such ciphers is via entirely distinct API calls that didn't exist before. | ||
| 45 | However existing API usage cannot be made to understand when an EVP_CIPHER | ||
| 46 | pointer, that has been passed to the caller, is no longer being used. | ||
| 47 | |||
| 48 | The other problem with the existing API w.r.t. to hooking EVP_CIPHER support | ||
| 49 | into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register | ||
| 50 | ciphers simultaneously registers cipher *types* and cipher *implementations* - | ||
| 51 | they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with | ||
| 52 | hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The | ||
| 53 | solution is necessarily that ENGINE-provided ciphers simply are not registered, | ||
| 54 | stored, or exposed to the caller in the same manner as existing ciphers. This is | ||
| 55 | especially necessary considering the fact ENGINE uses reference counts to allow | ||
| 56 | for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to | ||
| 57 | callers in the current API, support no such controls. | ||
| 58 | |||
| 59 | Another sticking point for integrating cipher support into ENGINE is linkage. | ||
| 60 | Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby | ||
| 61 | they are available *because* they're part of a giant ENGINE called "openssl". | ||
| 62 | Ie. all implementations *have* to come from an ENGINE, but we get round that by | ||
| 63 | having a giant ENGINE with all the software support encapsulated. This creates | ||
| 64 | linker hassles if nothing else - linking a 1-line application that calls 2 basic | ||
| 65 | RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of | ||
| 66 | ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we | ||
| 67 | continue with this approach for EVP_CIPHER support (even if it *was* possible) | ||
| 68 | we would lose our ability to link selectively by selectively loading certain | ||
| 69 | implementations of certain functionality. Touching any part of any kind of | ||
| 70 | crypto would result in massive static linkage of everything else. So the | ||
| 71 | solution is to change the way ENGINE feeds existing "classes", ie. how the | ||
| 72 | hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking | ||
| 73 | for EVP_CIPHER, and EVP_MD. | ||
| 74 | |||
| 75 | The way this is now being done is by mostly reverting back to how things used to | ||
| 76 | work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this | ||
| 77 | was previously replaced by an "ENGINE" pointer and all RSA code that required | ||
| 78 | the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to | ||
| 79 | temporarily get and use the ENGINE's RSA implementation. Apart from being more | ||
| 80 | efficient, switching back to each RSA having an RSA_METHOD pointer also allows | ||
| 81 | us to conceivably operate with *no* ENGINE. As we'll see, this removes any need | ||
| 82 | for a fallback ENGINE that encapsulates default implementations - we can simply | ||
| 83 | have our RSA structure pointing its RSA_METHOD pointer to the software | ||
| 84 | implementation and have its ENGINE pointer set to NULL. | ||
| 85 | |||
| 86 | A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases | ||
| 87 | turn out to be degenerate forms of the same thing. The EVP storage of ciphers, | ||
| 88 | and the existing EVP API functions that return "software" implementations and | ||
| 89 | descriptions remain untouched. However, the storage takes more meaning in terms | ||
| 90 | of "cipher description" and less meaning in terms of "implementation". When an | ||
| 91 | EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to | ||
| 92 | begin en/decryption, the hooking to ENGINE comes into play. What happens is that | ||
| 93 | cipher-specific ENGINE code is asked for an ENGINE pointer (a functional | ||
| 94 | reference) for any ENGINE that is registered to perform the algo/mode that the | ||
| 95 | provided EVP_CIPHER structure represents. Under normal circumstances, that | ||
| 96 | ENGINE code will return NULL because no ENGINEs will have had any cipher | ||
| 97 | implementations *registered*. As such, a NULL ENGINE pointer is stored in the | ||
| 98 | EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the | ||
| 99 | context and so is used as the implementation. Pretty much how things work now | ||
| 100 | except we'd have a redundant ENGINE pointer set to NULL and doing nothing. | ||
| 101 | |||
| 102 | Conversely, if an ENGINE *has* been registered to perform the algorithm/mode | ||
| 103 | combination represented by the provided EVP_CIPHER, then a functional reference | ||
| 104 | to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation. | ||
| 105 | That functional reference will be stored in the context (and released on | ||
| 106 | cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER | ||
| 107 | definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the | ||
| 108 | application will actually be replaced by an EVP_CIPHER from the registered | ||
| 109 | ENGINE - it will support the same algorithm/mode as the original but will be a | ||
| 110 | completely different implementation. Because this EVP_CIPHER isn't stored in the | ||
| 111 | EVP storage, nor is it returned to applications from traditional API functions, | ||
| 112 | there is no associated problem with it not having reference counts. And of | ||
| 113 | course, when one of these "private" cipher implementations is hooked into | ||
| 114 | EVP_CIPHER_CTX, it is done whilst the EVP_CIPHER_CTX holds a functional | ||
| 115 | reference to the ENGINE that owns it, thus the use of the ENGINE's EVP_CIPHER is | ||
| 116 | safe. | ||
| 117 | |||
| 118 | The "cipher-specific ENGINE code" I mentioned is implemented in tb_cipher.c but | ||
| 119 | in essence it is simply an instantiation of "ENGINE_TABLE" code for use by | ||
| 120 | EVP_CIPHER code. tb_digest.c is virtually identical but, of course, it is for | ||
| 121 | use by EVP_MD code. Ditto for tb_rsa.c, tb_dsa.c, etc. These instantiations of | ||
| 122 | ENGINE_TABLE essentially provide linker-separation of the classes so that even | ||
| 123 | if ENGINEs implement *all* possible algorithms, an application using only | ||
| 124 | EVP_CIPHER code will link at most code relating to EVP_CIPHER, tb_cipher.c, core | ||
| 125 | ENGINE code that is independant of class, and of course the ENGINE | ||
| 126 | implementation that the application loaded. It will *not* however link any | ||
| 127 | class-specific ENGINE code for digests, RSA, etc nor will it bleed over into | ||
| 128 | other APIs, such as the RSA/DSA/etc library code. | ||
| 129 | |||
| 130 | ENGINE_TABLE is a little more complicated than may seem necessary but this is | ||
| 131 | mostly to avoid a lot of "init()"-thrashing on ENGINEs (that may have to load | ||
| 132 | DSOs, and other expensive setup that shouldn't be thrashed unnecessarily) *and* | ||
| 133 | to duplicate "default" behaviour. Basically an ENGINE_TABLE instantiation, for | ||
| 134 | example tb_cipher.c, implements a hash-table keyed by integer "nid" values. | ||
| 135 | These nids provide the uniquenness of an algorithm/mode - and each nid will hash | ||
| 136 | to a potentially NULL "ENGINE_PILE". An ENGINE_PILE is essentially a list of | ||
| 137 | pointers to ENGINEs that implement that particular 'nid'. Each "pile" uses some | ||
| 138 | caching tricks such that requests on that 'nid' will be cached and all future | ||
| 139 | requests will return immediately (well, at least with minimal operation) unless | ||
| 140 | a change is made to the pile, eg. perhaps an ENGINE was unloaded. The reason is | ||
| 141 | that an application could have support for 10 ENGINEs statically linked | ||
| 142 | in, and the machine in question may not have any of the hardware those 10 | ||
| 143 | ENGINEs support. If each of those ENGINEs has a "des_cbc" implementation, we | ||
| 144 | want to avoid every EVP_CIPHER_CTX setup from trying (and failing) to initialise | ||
| 145 | each of those 10 ENGINEs. Instead, the first such request will try to do that | ||
| 146 | and will either return (and cache) a NULL ENGINE pointer or will return a | ||
| 147 | functional reference to the first that successfully initialised. In the latter | ||
| 148 | case it will also cache an extra functional reference to the ENGINE as a | ||
| 149 | "default" for that 'nid'. The caching is acknowledged by a 'uptodate' variable | ||
| 150 | that is unset only if un/registration takes place on that pile. Ie. if | ||
| 151 | implementations of "des_cbc" are added or removed. This behaviour can be | ||
| 152 | tweaked; the ENGINE_TABLE_FLAG_NOINIT value can be passed to | ||
| 153 | ENGINE_set_table_flags(), in which case the only ENGINEs that tb_cipher.c will | ||
| 154 | try to initialise from the "pile" will be those that are already initialised | ||
| 155 | (ie. it's simply an increment of the functional reference count, and no real | ||
| 156 | "initialisation" will take place). | ||
| 157 | |||
| 158 | RSA, DSA, DH, and RAND all have their own ENGINE_TABLE code as well, and the | ||
| 159 | difference is that they all use an implicit 'nid' of 1. Whereas EVP_CIPHERs are | ||
| 160 | actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is | ||
| 161 | not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are | ||
| 162 | necessarily interoperable and don't have different flavours, only different | ||
| 163 | implementations. In other words, the ENGINE_TABLE for RSA will either be empty, | ||
| 164 | or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile | ||
| 165 | represents ENGINEs that implement the single "type" of RSA there is. | ||
| 166 | |||
| 167 | Cleanup - the registration and unregistration may pose questions about how | ||
| 168 | cleanup works with the ENGINE_PILE doing all this caching nonsense (ie. when the | ||
| 169 | application or EVP_CIPHER code releases its last reference to an ENGINE, the | ||
| 170 | ENGINE_PILE code may still have references and thus those ENGINEs will stay | ||
| 171 | hooked in forever). The way this is handled is via "unregistration". With these | ||
| 172 | new ENGINE changes, an abstract ENGINE can be loaded and initialised, but that | ||
| 173 | is an algorithm-agnostic process. Even if initialised, it will not have | ||
| 174 | registered any of its implementations (to do so would link all class "table" | ||
| 175 | code despite the fact the application may use only ciphers, for example). This | ||
| 176 | is deliberately a distinct step. Moreover, registration and unregistration has | ||
| 177 | nothing to do with whether an ENGINE is *functional* or not (ie. you can even | ||
| 178 | register an ENGINE and its implementations without it being operational, you may | ||
| 179 | not even have the drivers to make it operate). What actually happens with | ||
| 180 | respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***" | ||
| 181 | functions. These functions are internal-only and each part of ENGINE code that | ||
| 182 | could require cleanup will, upon performing its first allocation, register a | ||
| 183 | callback with the "engine_cleanup" code. The other part of this that makes it | ||
| 184 | tick is that the ENGINE_TABLE instantiations (tb_***.c) use NULL as their | ||
| 185 | initialised state. So if RSA code asks for an ENGINE and no ENGINE has | ||
| 186 | registered an implementation, the code will simply return NULL and the tb_rsa.c | ||
| 187 | state will be unchanged. Thus, no cleanup is required unless registration takes | ||
| 188 | place. ENGINE_cleanup() will simply iterate across a list of registered cleanup | ||
| 189 | callbacks calling each in turn, and will then internally delete its own storage | ||
| 190 | (a STACK). When a cleanup callback is next registered (eg. if the cleanup() is | ||
| 191 | part of a gracefull restart and the application wants to cleanup all state then | ||
| 192 | start again), the internal STACK storage will be freshly allocated. This is much | ||
| 193 | the same as the situation in the ENGINE_TABLE instantiations ... NULL is the | ||
| 194 | initialised state, so only modification operations (not queries) will cause that | ||
| 195 | code to have to register a cleanup. | ||
| 196 | |||
| 197 | What else? The bignum callbacks and associated ENGINE functions have been | ||
| 198 | removed for two obvious reasons; (i) there was no way to generalise them to the | ||
| 199 | mechanism now used by RSA/DSA/..., because there's no such thing as a BIGNUM | ||
| 200 | method, and (ii) because of (i), there was no meaningful way for library or | ||
| 201 | application code to automatically hook and use ENGINE supplied bignum functions | ||
| 202 | anyway. Also, ENGINE_cpy() has been removed (although an internal-only version | ||
| 203 | exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good | ||
| 204 | one and now certainly doesn't make sense in any generalised way. Some of the | ||
| 205 | RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE | ||
| 206 | changes have now, as a consequence, been reverted back. This is because the | ||
| 207 | hooking of ENGINE is now automatic (and passive, it can interally use a NULL | ||
| 208 | ENGINE pointer to simply ignore ENGINE from then on). | ||
| 209 | |||
| 210 | Hell, that should be enough for now ... comments welcome: geoff@openssl.org | ||
| 211 | |||
