evp-pkcs11.c revision 1.3 1 1.1 christos /* $NetBSD: evp-pkcs11.c,v 1.3 2019/12/15 22:50:48 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (c) 2015-2016, Secure Endpoints Inc.
5 1.1 christos * All rights reserved.
6 1.1 christos *
7 1.1 christos * Redistribution and use in source and binary forms, with or without
8 1.1 christos * modification, are permitted provided that the following conditions
9 1.1 christos * are met:
10 1.1 christos *
11 1.1 christos * - Redistributions of source code must retain the above copyright
12 1.1 christos * notice, this list of conditions and the following disclaimer.
13 1.1 christos *
14 1.1 christos * - Redistributions in binary form must reproduce the above copyright
15 1.1 christos * notice, this list of conditions and the following disclaimer in
16 1.1 christos * the documentation and/or other materials provided with the
17 1.1 christos * distribution.
18 1.1 christos *
19 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 1.1 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 1.1 christos * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 1.1 christos * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 1.1 christos * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 1.1 christos * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 1.1 christos * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 1.1 christos * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 1.1 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 1.1 christos * OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.1 christos */
32 1.1 christos
33 1.1 christos /* PKCS#11 provider */
34 1.1 christos
35 1.1 christos #include <config.h>
36 1.1 christos #include <krb5/roken.h>
37 1.1 christos #include <assert.h>
38 1.1 christos #ifdef HAVE_DLFCN_H
39 1.1 christos #include <dlfcn.h>
40 1.1 christos #ifndef RTLD_LAZY
41 1.1 christos #define RTLD_LAZY 0
42 1.1 christos #endif
43 1.1 christos #ifndef RTLD_LOCAL
44 1.1 christos #define RTLD_LOCAL 0
45 1.1 christos #endif
46 1.1 christos #ifndef RTLD_GROUP
47 1.1 christos #define RTLD_GROUP 0
48 1.1 christos #endif
49 1.1 christos #ifndef RTLD_NODELETE
50 1.1 christos #define RTLD_NODELETE 0
51 1.1 christos #endif
52 1.1 christos #else
53 1.1 christos #error PKCS11 support requires dlfcn.h
54 1.1 christos #endif
55 1.1 christos
56 1.1 christos #include <krb5/heimbase.h>
57 1.1 christos
58 1.1 christos #include <evp.h>
59 1.1 christos #include <evp-hcrypto.h>
60 1.1 christos #include <evp-pkcs11.h>
61 1.1 christos
62 1.1 christos #include <ref/pkcs11.h>
63 1.1 christos
64 1.1 christos #if __sun && !defined(PKCS11_MODULE_PATH)
65 1.3 christos # ifdef _LP64
66 1.1 christos # define PKCS11_MODULE_PATH "/usr/lib/64/libpkcs11.so"
67 1.1 christos # else
68 1.1 christos # define PKCS11_MODULE_PATH "/usr/lib/libpkcs11.so"
69 1.1 christos # endif
70 1.1 christos #elif defined(__linux__)
71 1.1 christos /*
72 1.1 christos * XXX We should have an autoconf check for OpenCryptoki and such
73 1.1 christos * things. However, there's no AC_CHECK_OBJECT(), and we'd have to
74 1.1 christos * write one. Today I'm feeling lazy. Another possibility would be to
75 1.1 christos * have a symlink from the libdir we'll install into, and then we could
76 1.1 christos * dlopen() that on all platforms.
77 1.1 christos *
78 1.1 christos * XXX Also, we should pick an appropriate shared object based on 32- vs
79 1.1 christos * 64-bits.
80 1.1 christos */
81 1.1 christos # define PKCS11_MODULE_PATH "/usr/lib/pkcs11/PKCS11_API.so"
82 1.1 christos #endif
83 1.1 christos
84 1.1 christos static CK_FUNCTION_LIST_PTR p11_module;
85 1.1 christos
86 1.1 christos static int
87 1.1 christos p11_cleanup(EVP_CIPHER_CTX *ctx);
88 1.1 christos
89 1.1 christos struct pkcs11_cipher_ctx {
90 1.1 christos CK_SESSION_HANDLE hSession;
91 1.1 christos CK_OBJECT_HANDLE hSecret;
92 1.1 christos };
93 1.1 christos
94 1.1 christos struct pkcs11_md_ctx {
95 1.1 christos CK_SESSION_HANDLE hSession;
96 1.1 christos };
97 1.1 christos
98 1.1 christos static void *pkcs11_module_handle;
99 1.3 christos
100 1.3 christos static CK_RV
101 1.3 christos p11_module_load(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
102 1.1 christos {
103 1.1 christos CK_RV rv;
104 1.1 christos CK_RV (*C_GetFunctionList_fn)(CK_FUNCTION_LIST_PTR_PTR);
105 1.3 christos
106 1.3 christos *ppFunctionList = NULL;
107 1.1 christos
108 1.1 christos if (!issuid()) {
109 1.1 christos char *pkcs11ModulePath = getenv("PKCS11_MODULE_PATH");
110 1.1 christos if (pkcs11ModulePath != NULL) {
111 1.1 christos pkcs11_module_handle =
112 1.1 christos dlopen(pkcs11ModulePath,
113 1.1 christos RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP | RTLD_NODELETE);
114 1.1 christos if (pkcs11_module_handle == NULL)
115 1.3 christos fprintf(stderr, "p11_module_load(%s): %s\n", pkcs11ModulePath, dlerror());
116 1.1 christos }
117 1.1 christos }
118 1.1 christos #ifdef PKCS11_MODULE_PATH
119 1.1 christos if (pkcs11_module_handle == NULL) {
120 1.1 christos pkcs11_module_handle =
121 1.1 christos dlopen(PKCS11_MODULE_PATH,
122 1.1 christos RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP | RTLD_NODELETE);
123 1.1 christos if (pkcs11_module_handle == NULL)
124 1.3 christos fprintf(stderr, "p11_module_load(%s): %s\n", PKCS11_MODULE_PATH, dlerror());
125 1.1 christos }
126 1.1 christos #endif
127 1.1 christos if (pkcs11_module_handle == NULL)
128 1.3 christos return CKR_LIBRARY_LOAD_FAILED;
129 1.1 christos
130 1.1 christos C_GetFunctionList_fn = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
131 1.1 christos dlsym(pkcs11_module_handle, "C_GetFunctionList");
132 1.3 christos if (C_GetFunctionList_fn == NULL) {
133 1.3 christos dlclose(pkcs11_module_handle);
134 1.3 christos return CKR_LIBRARY_LOAD_FAILED;
135 1.3 christos }
136 1.1 christos
137 1.3 christos rv = C_GetFunctionList_fn(ppFunctionList);
138 1.3 christos if (rv != CKR_OK) {
139 1.3 christos dlclose(pkcs11_module_handle);
140 1.3 christos return rv;
141 1.3 christos }
142 1.1 christos
143 1.3 christos return CKR_OK;
144 1.3 christos }
145 1.1 christos
146 1.3 christos static void
147 1.3 christos p11_module_load_once(void *context)
148 1.3 christos {
149 1.3 christos p11_module_load((CK_FUNCTION_LIST_PTR_PTR)context);
150 1.1 christos }
151 1.1 christos
152 1.1 christos static CK_RV
153 1.1 christos p11_module_init(void)
154 1.1 christos {
155 1.3 christos static heim_base_once_t once = HEIM_BASE_ONCE_INIT;
156 1.3 christos CK_RV rv;
157 1.1 christos
158 1.3 christos heim_base_once_f(&once, &p11_module, p11_module_load_once);
159 1.1 christos
160 1.3 christos if (p11_module == NULL)
161 1.3 christos return CKR_LIBRARY_LOAD_FAILED;
162 1.3 christos
163 1.3 christos /*
164 1.3 christos * Call C_Initialize() on every call, because it will be invalid after fork().
165 1.3 christos * Caching the initialization status using a once control and invalidating it
166 1.3 christos * on fork provided no measurable performance benefit on Solaris 11. Other
167 1.3 christos * approaches would not be thread-safe or would involve more intrusive code
168 1.3 christos * changes, such as exposing heimbase's atomics.
169 1.3 christos */
170 1.3 christos rv = p11_module->C_Initialize(NULL);
171 1.3 christos if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED)
172 1.3 christos rv = CKR_OK;
173 1.3 christos
174 1.3 christos return rv;
175 1.1 christos }
176 1.1 christos
177 1.1 christos static CK_RV
178 1.3 christos p11_session_init(CK_MECHANISM_TYPE mechanismType,
179 1.3 christos CK_SESSION_HANDLE_PTR phSession,
180 1.3 christos CK_FLAGS *pFlags)
181 1.1 christos {
182 1.1 christos CK_RV rv;
183 1.1 christos CK_ULONG i, ulSlotCount = 0;
184 1.1 christos CK_SLOT_ID_PTR pSlotList = NULL;
185 1.1 christos CK_MECHANISM_INFO info;
186 1.1 christos
187 1.1 christos if (phSession != NULL)
188 1.1 christos *phSession = CK_INVALID_HANDLE;
189 1.1 christos
190 1.3 christos *pFlags = 0;
191 1.3 christos
192 1.1 christos rv = p11_module_init();
193 1.1 christos if (rv != CKR_OK)
194 1.1 christos goto cleanup;
195 1.1 christos
196 1.1 christos assert(p11_module != NULL);
197 1.1 christos
198 1.1 christos rv = p11_module->C_GetSlotList(CK_FALSE, NULL, &ulSlotCount);
199 1.1 christos if (rv != CKR_OK)
200 1.1 christos goto cleanup;
201 1.1 christos
202 1.1 christos pSlotList = (CK_SLOT_ID_PTR)calloc(ulSlotCount, sizeof(CK_SLOT_ID));
203 1.1 christos if (pSlotList == NULL) {
204 1.1 christos rv = CKR_HOST_MEMORY;
205 1.1 christos goto cleanup;
206 1.1 christos }
207 1.1 christos
208 1.1 christos rv = p11_module->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
209 1.1 christos if (rv != CKR_OK)
210 1.1 christos goto cleanup;
211 1.1 christos
212 1.1 christos /*
213 1.1 christos * Note that this approach of using the first slot that supports the desired
214 1.1 christos * mechanism may not always be what the user wants (for example it may prefer
215 1.1 christos * software to hardware crypto). We're going to assume that this code will be
216 1.1 christos * principally used on Solaris (which has a meta-slot provider that sorts by
217 1.1 christos * hardware first) or in situations where the user can configure the slots in
218 1.1 christos * order of provider preference. In the future we should make this configurable.
219 1.1 christos */
220 1.1 christos for (i = 0; i < ulSlotCount; i++) {
221 1.1 christos rv = p11_module->C_GetMechanismInfo(pSlotList[i], mechanismType, &info);
222 1.3 christos if (rv == CKR_OK) {
223 1.3 christos *pFlags = info.flags;
224 1.3 christos break;
225 1.3 christos }
226 1.1 christos }
227 1.1 christos
228 1.1 christos if (i == ulSlotCount) {
229 1.1 christos rv = CKR_MECHANISM_INVALID;
230 1.1 christos goto cleanup;
231 1.1 christos }
232 1.1 christos
233 1.1 christos if (phSession != NULL) {
234 1.1 christos rv = p11_module->C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, NULL, NULL, phSession);
235 1.1 christos if (rv != CKR_OK)
236 1.1 christos goto cleanup;
237 1.1 christos }
238 1.1 christos
239 1.1 christos cleanup:
240 1.1 christos free(pSlotList);
241 1.1 christos
242 1.1 christos return rv;
243 1.1 christos }
244 1.1 christos
245 1.1 christos static int
246 1.3 christos p11_mech_available_p(CK_MECHANISM_TYPE mechanismType, CK_FLAGS reqFlags)
247 1.1 christos {
248 1.3 christos CK_RV rv;
249 1.3 christos CK_FLAGS flags;
250 1.3 christos
251 1.3 christos rv = p11_session_init(mechanismType, NULL, &flags);
252 1.3 christos if (rv != CKR_OK)
253 1.3 christos return 0;
254 1.3 christos
255 1.3 christos return (flags & reqFlags) == reqFlags;
256 1.1 christos }
257 1.1 christos
258 1.1 christos static CK_KEY_TYPE
259 1.1 christos p11_key_type_for_mech(CK_MECHANISM_TYPE mechanismType)
260 1.1 christos {
261 1.1 christos CK_KEY_TYPE keyType = 0;
262 1.1 christos
263 1.1 christos switch (mechanismType) {
264 1.1 christos case CKM_RC2_CBC:
265 1.1 christos keyType = CKK_RC2;
266 1.1 christos break;
267 1.1 christos case CKM_RC4:
268 1.1 christos keyType = CKK_RC4;
269 1.1 christos break;
270 1.1 christos case CKM_DES_CBC:
271 1.1 christos keyType = CKK_DES;
272 1.1 christos break;
273 1.1 christos case CKM_DES3_CBC:
274 1.1 christos keyType = CKK_DES3;
275 1.1 christos break;
276 1.1 christos case CKM_AES_CBC:
277 1.1 christos case CKM_AES_CFB8:
278 1.1 christos keyType = CKK_AES;
279 1.1 christos break;
280 1.1 christos case CKM_CAMELLIA_CBC:
281 1.1 christos keyType = CKK_CAMELLIA;
282 1.1 christos break;
283 1.1 christos default:
284 1.1 christos assert(0 && "Unknown PKCS#11 mechanism type");
285 1.1 christos break;
286 1.1 christos }
287 1.1 christos
288 1.1 christos return keyType;
289 1.1 christos }
290 1.1 christos
291 1.1 christos static int
292 1.1 christos p11_key_init(EVP_CIPHER_CTX *ctx,
293 1.1 christos const unsigned char *key,
294 1.1 christos const unsigned char *iv,
295 1.1 christos int encp)
296 1.1 christos {
297 1.1 christos CK_RV rv;
298 1.1 christos CK_BBOOL bFalse = CK_FALSE;
299 1.1 christos CK_BBOOL bTrue = CK_TRUE;
300 1.1 christos CK_MECHANISM_TYPE mechanismType = (CK_MECHANISM_TYPE)ctx->cipher->app_data;
301 1.1 christos CK_KEY_TYPE keyType = p11_key_type_for_mech(mechanismType);
302 1.1 christos CK_OBJECT_CLASS objectClass = CKO_SECRET_KEY;
303 1.1 christos CK_ATTRIBUTE_TYPE op = encp ? CKA_ENCRYPT : CKA_DECRYPT;
304 1.1 christos CK_ATTRIBUTE attributes[] = {
305 1.1 christos { CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) },
306 1.1 christos { CKA_CLASS, &objectClass, sizeof(objectClass) },
307 1.1 christos { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
308 1.1 christos { CKA_TOKEN, &bFalse, sizeof(bFalse) },
309 1.1 christos { CKA_PRIVATE, &bFalse, sizeof(bFalse) },
310 1.1 christos { CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
311 1.1 christos { CKA_VALUE, (void *)key, ctx->key_len },
312 1.1 christos { op, &bTrue, sizeof(bTrue) }
313 1.1 christos };
314 1.3 christos CK_MECHANISM mechanism = {
315 1.3 christos mechanismType,
316 1.3 christos ctx->cipher->iv_len ? ctx->iv : NULL,
317 1.3 christos ctx->cipher->iv_len
318 1.3 christos };
319 1.1 christos struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
320 1.3 christos CK_FLAGS flags;
321 1.1 christos
322 1.3 christos rv = CKR_OK;
323 1.3 christos
324 1.3 christos if (p11ctx->hSession != CK_INVALID_HANDLE && key != NULL)
325 1.3 christos p11_cleanup(ctx); /* refresh session with new key */
326 1.3 christos
327 1.3 christos if (p11ctx->hSession == CK_INVALID_HANDLE) {
328 1.3 christos rv = p11_session_init(mechanismType, &p11ctx->hSession, &flags);
329 1.3 christos if (rv != CKR_OK)
330 1.3 christos goto cleanup;
331 1.3 christos
332 1.3 christos if ((flags & (CKF_ENCRYPT|CKF_DECRYPT)) != (CKF_ENCRYPT|CKF_DECRYPT)) {
333 1.3 christos rv = CKR_MECHANISM_INVALID;
334 1.3 christos goto cleanup;
335 1.3 christos }
336 1.3 christos }
337 1.3 christos
338 1.3 christos if (key != NULL) {
339 1.3 christos assert(p11_module != NULL);
340 1.3 christos assert(p11ctx->hSecret == CK_INVALID_HANDLE);
341 1.1 christos
342 1.3 christos rv = p11_module->C_CreateObject(p11ctx->hSession, attributes,
343 1.3 christos sizeof(attributes) / sizeof(attributes[0]),
344 1.3 christos &p11ctx->hSecret);
345 1.3 christos if (rv != CKR_OK)
346 1.3 christos goto cleanup;
347 1.3 christos }
348 1.1 christos
349 1.3 christos if (p11ctx->hSecret != CK_INVALID_HANDLE) {
350 1.3 christos if (op == CKA_ENCRYPT)
351 1.3 christos rv = p11_module->C_EncryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
352 1.3 christos else
353 1.3 christos rv = p11_module->C_DecryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
354 1.3 christos if (rv != CKR_OK)
355 1.3 christos goto cleanup;
356 1.3 christos }
357 1.1 christos
358 1.1 christos cleanup:
359 1.1 christos if (rv != CKR_OK)
360 1.1 christos p11_cleanup(ctx);
361 1.1 christos
362 1.1 christos return rv == CKR_OK;
363 1.1 christos }
364 1.1 christos
365 1.1 christos static int
366 1.1 christos p11_do_cipher(EVP_CIPHER_CTX *ctx,
367 1.1 christos unsigned char *out,
368 1.1 christos const unsigned char *in,
369 1.1 christos unsigned int size)
370 1.1 christos {
371 1.1 christos struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
372 1.3 christos CK_RV rv;
373 1.1 christos CK_ULONG ulCipherTextLen = size;
374 1.1 christos
375 1.1 christos assert(p11_module != NULL);
376 1.1 christos assert(EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_STREAM_CIPHER ||
377 1.1 christos (size % ctx->cipher->block_size) == 0);
378 1.1 christos
379 1.3 christos if (ctx->encrypt)
380 1.3 christos rv = p11_module->C_EncryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen);
381 1.3 christos else
382 1.3 christos rv = p11_module->C_DecryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen);
383 1.1 christos
384 1.1 christos return rv == CKR_OK;
385 1.1 christos }
386 1.1 christos
387 1.1 christos static int
388 1.1 christos p11_cleanup(EVP_CIPHER_CTX *ctx)
389 1.1 christos {
390 1.1 christos struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
391 1.1 christos
392 1.1 christos if (p11ctx->hSecret != CK_INVALID_HANDLE) {
393 1.1 christos p11_module->C_DestroyObject(p11ctx->hSession, p11ctx->hSecret);
394 1.1 christos p11ctx->hSecret = CK_INVALID_HANDLE;
395 1.1 christos }
396 1.1 christos if (p11ctx->hSession != CK_INVALID_HANDLE) {
397 1.1 christos p11_module->C_CloseSession(p11ctx->hSession);
398 1.1 christos p11ctx->hSession = CK_INVALID_HANDLE;
399 1.1 christos }
400 1.1 christos
401 1.1 christos return 1;
402 1.1 christos }
403 1.1 christos
404 1.1 christos static int
405 1.3 christos p11_md_cleanup(EVP_MD_CTX *ctx);
406 1.3 christos
407 1.3 christos static int
408 1.1 christos p11_md_hash_init(CK_MECHANISM_TYPE mechanismType, EVP_MD_CTX *ctx)
409 1.1 christos {
410 1.1 christos struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx;
411 1.1 christos CK_RV rv;
412 1.3 christos CK_FLAGS flags;
413 1.3 christos CK_MECHANISM mechanism = { mechanismType, NULL, 0 };
414 1.1 christos
415 1.3 christos if (p11ctx->hSession != CK_INVALID_HANDLE)
416 1.3 christos p11_md_cleanup(ctx);
417 1.1 christos
418 1.3 christos rv = p11_session_init(mechanismType, &p11ctx->hSession, &flags);
419 1.3 christos if (rv != CKR_OK)
420 1.3 christos goto cleanup;
421 1.1 christos
422 1.3 christos if ((flags & CKF_DIGEST) != CKF_DIGEST) {
423 1.3 christos rv = CKR_MECHANISM_INVALID;
424 1.3 christos goto cleanup;
425 1.1 christos }
426 1.1 christos
427 1.3 christos assert(p11_module != NULL);
428 1.3 christos
429 1.3 christos rv = p11_module->C_DigestInit(p11ctx->hSession, &mechanism);
430 1.3 christos
431 1.3 christos cleanup:
432 1.1 christos return rv == CKR_OK;
433 1.1 christos }
434 1.1 christos
435 1.1 christos static int
436 1.1 christos p11_md_update(EVP_MD_CTX *ctx, const void *data, size_t length)
437 1.1 christos {
438 1.1 christos struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx;
439 1.1 christos CK_RV rv;
440 1.1 christos
441 1.1 christos assert(p11_module != NULL);
442 1.3 christos assert(data != NULL || length == 0);
443 1.1 christos
444 1.3 christos rv = p11_module->C_DigestUpdate(p11ctx->hSession,
445 1.3 christos data ? (CK_BYTE_PTR)data : (CK_BYTE_PTR)"",
446 1.3 christos length);
447 1.1 christos
448 1.1 christos return rv == CKR_OK;
449 1.1 christos }
450 1.1 christos
451 1.1 christos static int
452 1.1 christos p11_md_final(void *digest, EVP_MD_CTX *ctx)
453 1.1 christos {
454 1.1 christos struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx;
455 1.1 christos CK_RV rv;
456 1.1 christos CK_ULONG digestLen = 0;
457 1.1 christos
458 1.1 christos assert(p11_module != NULL);
459 1.1 christos
460 1.1 christos rv = p11_module->C_DigestFinal(p11ctx->hSession, NULL, &digestLen);
461 1.1 christos if (rv == CKR_OK)
462 1.1 christos rv = p11_module->C_DigestFinal(p11ctx->hSession, digest, &digestLen);
463 1.1 christos
464 1.1 christos return rv == CKR_OK;
465 1.1 christos }
466 1.1 christos
467 1.1 christos static int
468 1.1 christos p11_md_cleanup(EVP_MD_CTX *ctx)
469 1.1 christos {
470 1.1 christos struct pkcs11_md_ctx *p11ctx = (struct pkcs11_md_ctx *)ctx;
471 1.1 christos CK_RV rv;
472 1.1 christos
473 1.1 christos assert(p11_module != NULL);
474 1.1 christos
475 1.1 christos rv = p11_module->C_CloseSession(p11ctx->hSession);
476 1.1 christos if (rv == CKR_OK)
477 1.1 christos p11ctx->hSession = CK_INVALID_HANDLE;
478 1.1 christos
479 1.1 christos return rv == CKR_OK;
480 1.1 christos }
481 1.1 christos
482 1.1 christos #define PKCS11_CIPHER_ALGORITHM(name, mechanismType, block_size, \
483 1.1 christos key_len, iv_len, flags) \
484 1.1 christos \
485 1.1 christos static EVP_CIPHER \
486 1.1 christos pkcs11_##name = { \
487 1.1 christos 0, \
488 1.1 christos block_size, \
489 1.1 christos key_len, \
490 1.1 christos iv_len, \
491 1.3 christos (flags) | EVP_CIPH_ALWAYS_CALL_INIT, \
492 1.1 christos p11_key_init, \
493 1.1 christos p11_do_cipher, \
494 1.1 christos p11_cleanup, \
495 1.1 christos sizeof(struct pkcs11_cipher_ctx), \
496 1.1 christos NULL, \
497 1.1 christos NULL, \
498 1.1 christos NULL, \
499 1.1 christos (void *)mechanismType \
500 1.1 christos }; \
501 1.1 christos \
502 1.1 christos const EVP_CIPHER * \
503 1.1 christos hc_EVP_pkcs11_##name(void) \
504 1.1 christos { \
505 1.3 christos if (p11_mech_available_p(mechanismType, CKF_ENCRYPT|CKF_DECRYPT)) \
506 1.1 christos return &pkcs11_##name; \
507 1.1 christos else \
508 1.1 christos return NULL; \
509 1.1 christos } \
510 1.1 christos \
511 1.1 christos static void \
512 1.1 christos pkcs11_hcrypto_##name##_init_once(void *context) \
513 1.1 christos { \
514 1.1 christos const EVP_CIPHER *cipher; \
515 1.1 christos \
516 1.1 christos cipher = hc_EVP_pkcs11_ ##name(); \
517 1.1 christos if (cipher == NULL && HCRYPTO_FALLBACK) \
518 1.1 christos cipher = hc_EVP_hcrypto_ ##name(); \
519 1.1 christos \
520 1.1 christos *((const EVP_CIPHER **)context) = cipher; \
521 1.1 christos } \
522 1.1 christos \
523 1.1 christos const EVP_CIPHER * \
524 1.1 christos hc_EVP_pkcs11_hcrypto_##name(void) \
525 1.1 christos { \
526 1.1 christos static const EVP_CIPHER *__cipher; \
527 1.1 christos static heim_base_once_t __init = HEIM_BASE_ONCE_INIT; \
528 1.1 christos \
529 1.1 christos heim_base_once_f(&__init, &__cipher, \
530 1.1 christos pkcs11_hcrypto_##name##_init_once); \
531 1.1 christos \
532 1.1 christos return __cipher; \
533 1.1 christos }
534 1.1 christos
535 1.1 christos #define PKCS11_MD_ALGORITHM(name, mechanismType, hash_size, block_size) \
536 1.1 christos \
537 1.1 christos static int p11_##name##_init(EVP_MD_CTX *ctx) \
538 1.1 christos { \
539 1.1 christos return p11_md_hash_init(mechanismType, ctx); \
540 1.1 christos } \
541 1.1 christos \
542 1.1 christos const EVP_MD * \
543 1.1 christos hc_EVP_pkcs11_##name(void) \
544 1.1 christos { \
545 1.1 christos static struct hc_evp_md name = { \
546 1.1 christos hash_size, \
547 1.1 christos block_size, \
548 1.1 christos sizeof(struct pkcs11_md_ctx), \
549 1.1 christos p11_##name##_init, \
550 1.1 christos p11_md_update, \
551 1.1 christos p11_md_final, \
552 1.1 christos p11_md_cleanup \
553 1.1 christos }; \
554 1.1 christos \
555 1.3 christos if (p11_mech_available_p(mechanismType, CKF_DIGEST)) \
556 1.1 christos return &name; \
557 1.1 christos else \
558 1.1 christos return NULL; \
559 1.1 christos } \
560 1.1 christos \
561 1.1 christos static void \
562 1.1 christos pkcs11_hcrypto_##name##_init_once(void *context) \
563 1.1 christos { \
564 1.1 christos const EVP_MD *md; \
565 1.1 christos \
566 1.1 christos md = hc_EVP_pkcs11_ ##name(); \
567 1.1 christos if (md == NULL && HCRYPTO_FALLBACK) \
568 1.1 christos md = hc_EVP_hcrypto_ ##name(); \
569 1.1 christos \
570 1.1 christos *((const EVP_MD **)context) = md; \
571 1.1 christos } \
572 1.1 christos \
573 1.1 christos const EVP_MD * \
574 1.1 christos hc_EVP_pkcs11_hcrypto_##name(void) \
575 1.1 christos { \
576 1.1 christos static const EVP_MD *__md; \
577 1.1 christos static heim_base_once_t __init = HEIM_BASE_ONCE_INIT; \
578 1.1 christos \
579 1.1 christos heim_base_once_f(&__init, &__md, \
580 1.1 christos pkcs11_hcrypto_##name##_init_once); \
581 1.1 christos \
582 1.1 christos return __md; \
583 1.1 christos }
584 1.1 christos
585 1.1 christos #define PKCS11_MD_ALGORITHM_UNAVAILABLE(name) \
586 1.1 christos \
587 1.1 christos const EVP_MD * \
588 1.1 christos hc_EVP_pkcs11_##name(void) \
589 1.1 christos { \
590 1.1 christos return NULL; \
591 1.1 christos } \
592 1.1 christos \
593 1.1 christos const EVP_MD * \
594 1.1 christos hc_EVP_pkcs11_hcrypto_##name(void) \
595 1.1 christos { \
596 1.1 christos return hc_EVP_hcrypto_ ##name(); \
597 1.1 christos }
598 1.1 christos
599 1.1 christos /**
600 1.1 christos * The triple DES cipher type (PKCS#11 provider)
601 1.1 christos *
602 1.1 christos * @return the DES-EDE3-CBC EVP_CIPHER pointer.
603 1.1 christos *
604 1.1 christos * @ingroup hcrypto_evp
605 1.1 christos */
606 1.1 christos
607 1.1 christos PKCS11_CIPHER_ALGORITHM(des_ede3_cbc,
608 1.1 christos CKM_DES3_CBC,
609 1.1 christos 8,
610 1.1 christos 24,
611 1.1 christos 8,
612 1.1 christos EVP_CIPH_CBC_MODE)
613 1.1 christos
614 1.1 christos /**
615 1.1 christos * The DES cipher type (PKCS#11 provider)
616 1.1 christos *
617 1.1 christos * @return the DES-CBC EVP_CIPHER pointer.
618 1.1 christos *
619 1.1 christos * @ingroup hcrypto_evp
620 1.1 christos */
621 1.1 christos
622 1.1 christos PKCS11_CIPHER_ALGORITHM(des_cbc,
623 1.1 christos CKM_DES_CBC,
624 1.1 christos 8,
625 1.1 christos 8,
626 1.1 christos 8,
627 1.1 christos EVP_CIPH_CBC_MODE)
628 1.1 christos
629 1.1 christos /**
630 1.1 christos * The AES-128 cipher type (PKCS#11 provider)
631 1.1 christos *
632 1.1 christos * @return the AES-128-CBC EVP_CIPHER pointer.
633 1.1 christos *
634 1.1 christos * @ingroup hcrypto_evp
635 1.1 christos */
636 1.1 christos
637 1.1 christos PKCS11_CIPHER_ALGORITHM(aes_128_cbc,
638 1.1 christos CKM_AES_CBC,
639 1.1 christos 16,
640 1.1 christos 16,
641 1.1 christos 16,
642 1.1 christos EVP_CIPH_CBC_MODE)
643 1.1 christos
644 1.1 christos /**
645 1.1 christos * The AES-192 cipher type (PKCS#11 provider)
646 1.1 christos *
647 1.1 christos * @return the AES-192-CBC EVP_CIPHER pointer.
648 1.1 christos *
649 1.1 christos * @ingroup hcrypto_evp
650 1.1 christos */
651 1.1 christos
652 1.1 christos PKCS11_CIPHER_ALGORITHM(aes_192_cbc,
653 1.1 christos CKM_AES_CBC,
654 1.1 christos 16,
655 1.1 christos 24,
656 1.1 christos 16,
657 1.1 christos EVP_CIPH_CBC_MODE)
658 1.1 christos
659 1.1 christos /**
660 1.1 christos * The AES-256 cipher type (PKCS#11 provider)
661 1.1 christos *
662 1.1 christos * @return the AES-256-CBC EVP_CIPHER pointer.
663 1.1 christos *
664 1.1 christos * @ingroup hcrypto_evp
665 1.1 christos */
666 1.1 christos
667 1.1 christos PKCS11_CIPHER_ALGORITHM(aes_256_cbc,
668 1.1 christos CKM_AES_CBC,
669 1.1 christos 16,
670 1.1 christos 32,
671 1.1 christos 16,
672 1.1 christos EVP_CIPH_CBC_MODE)
673 1.1 christos
674 1.1 christos /**
675 1.1 christos * The AES-128 CFB8 cipher type (PKCS#11 provider)
676 1.1 christos *
677 1.1 christos * @return the AES-128-CFB8 EVP_CIPHER pointer.
678 1.1 christos *
679 1.1 christos * @ingroup hcrypto_evp
680 1.1 christos */
681 1.1 christos
682 1.1 christos PKCS11_CIPHER_ALGORITHM(aes_128_cfb8,
683 1.1 christos CKM_AES_CFB8,
684 1.1 christos 16,
685 1.1 christos 16,
686 1.1 christos 16,
687 1.1 christos EVP_CIPH_CFB8_MODE)
688 1.1 christos
689 1.1 christos /**
690 1.1 christos * The AES-192 CFB8 cipher type (PKCS#11 provider)
691 1.1 christos *
692 1.1 christos * @return the AES-192-CFB8 EVP_CIPHER pointer.
693 1.1 christos *
694 1.1 christos * @ingroup hcrypto_evp
695 1.1 christos */
696 1.1 christos
697 1.1 christos PKCS11_CIPHER_ALGORITHM(aes_192_cfb8,
698 1.1 christos CKM_AES_CFB8,
699 1.1 christos 16,
700 1.1 christos 24,
701 1.1 christos 16,
702 1.1 christos EVP_CIPH_CFB8_MODE)
703 1.1 christos
704 1.1 christos /**
705 1.1 christos * The AES-256 CFB8 cipher type (PKCS#11 provider)
706 1.1 christos *
707 1.1 christos * @return the AES-256-CFB8 EVP_CIPHER pointer.
708 1.1 christos *
709 1.1 christos * @ingroup hcrypto_evp
710 1.1 christos */
711 1.1 christos
712 1.1 christos PKCS11_CIPHER_ALGORITHM(aes_256_cfb8,
713 1.1 christos CKM_AES_CFB8,
714 1.1 christos 16,
715 1.1 christos 32,
716 1.1 christos 16,
717 1.1 christos EVP_CIPH_CFB8_MODE)
718 1.1 christos
719 1.1 christos /**
720 1.1 christos * The RC2 cipher type - PKCS#11
721 1.1 christos *
722 1.1 christos * @return the RC2 EVP_CIPHER pointer.
723 1.1 christos *
724 1.1 christos * @ingroup hcrypto_evp
725 1.1 christos */
726 1.1 christos
727 1.1 christos PKCS11_CIPHER_ALGORITHM(rc2_cbc,
728 1.1 christos CKM_RC2_CBC,
729 1.1 christos 8,
730 1.1 christos 16,
731 1.1 christos 8,
732 1.1 christos EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH)
733 1.1 christos
734 1.1 christos /**
735 1.1 christos * The RC2-40 cipher type - PKCS#11
736 1.1 christos *
737 1.1 christos * @return the RC2-40 EVP_CIPHER pointer.
738 1.1 christos *
739 1.1 christos * @ingroup hcrypto_evp
740 1.1 christos */
741 1.1 christos
742 1.1 christos PKCS11_CIPHER_ALGORITHM(rc2_40_cbc,
743 1.1 christos CKM_RC2_CBC,
744 1.1 christos 8,
745 1.1 christos 5,
746 1.1 christos 8,
747 1.1 christos EVP_CIPH_CBC_MODE)
748 1.1 christos
749 1.1 christos /**
750 1.1 christos * The RC2-64 cipher type - PKCS#11
751 1.1 christos *
752 1.1 christos * @return the RC2-64 EVP_CIPHER pointer.
753 1.1 christos *
754 1.1 christos * @ingroup hcrypto_evp
755 1.1 christos */
756 1.1 christos
757 1.1 christos PKCS11_CIPHER_ALGORITHM(rc2_64_cbc,
758 1.1 christos CKM_RC2_CBC,
759 1.1 christos 8,
760 1.1 christos 8,
761 1.1 christos 8,
762 1.1 christos EVP_CIPH_CBC_MODE)
763 1.1 christos
764 1.1 christos /**
765 1.1 christos * The Camellia-128 cipher type - PKCS#11
766 1.1 christos *
767 1.1 christos * @return the Camellia-128 EVP_CIPHER pointer.
768 1.1 christos *
769 1.1 christos * @ingroup hcrypto_evp
770 1.1 christos */
771 1.1 christos
772 1.1 christos PKCS11_CIPHER_ALGORITHM(camellia_128_cbc,
773 1.1 christos CKM_CAMELLIA_CBC,
774 1.1 christos 16,
775 1.1 christos 16,
776 1.1 christos 16,
777 1.1 christos EVP_CIPH_CBC_MODE)
778 1.1 christos
779 1.1 christos /**
780 1.1 christos * The Camellia-198 cipher type - PKCS#11
781 1.1 christos *
782 1.1 christos * @return the Camellia-198 EVP_CIPHER pointer.
783 1.1 christos *
784 1.1 christos * @ingroup hcrypto_evp
785 1.1 christos */
786 1.1 christos
787 1.1 christos PKCS11_CIPHER_ALGORITHM(camellia_192_cbc,
788 1.1 christos CKM_CAMELLIA_CBC,
789 1.1 christos 16,
790 1.1 christos 24,
791 1.1 christos 16,
792 1.1 christos EVP_CIPH_CBC_MODE)
793 1.1 christos
794 1.1 christos /**
795 1.1 christos * The Camellia-256 cipher type - PKCS#11
796 1.1 christos *
797 1.1 christos * @return the Camellia-256 EVP_CIPHER pointer.
798 1.1 christos *
799 1.1 christos * @ingroup hcrypto_evp
800 1.1 christos */
801 1.1 christos
802 1.1 christos PKCS11_CIPHER_ALGORITHM(camellia_256_cbc,
803 1.1 christos CKM_CAMELLIA_CBC,
804 1.1 christos 16,
805 1.1 christos 32,
806 1.1 christos 16,
807 1.1 christos EVP_CIPH_CBC_MODE)
808 1.1 christos
809 1.1 christos /**
810 1.1 christos * The RC4 cipher type (PKCS#11 provider)
811 1.1 christos *
812 1.1 christos * @return the RC4 EVP_CIPHER pointer.
813 1.1 christos *
814 1.1 christos * @ingroup hcrypto_evp
815 1.1 christos */
816 1.1 christos
817 1.1 christos PKCS11_CIPHER_ALGORITHM(rc4,
818 1.1 christos CKM_RC4,
819 1.1 christos 1,
820 1.1 christos 16,
821 1.1 christos 0,
822 1.1 christos EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH)
823 1.1 christos
824 1.1 christos /**
825 1.1 christos * The RC4-40 cipher type (PKCS#11 provider)
826 1.1 christos *
827 1.1 christos * @return the RC4 EVP_CIPHER pointer.
828 1.1 christos *
829 1.1 christos * @ingroup hcrypto_evp
830 1.1 christos */
831 1.1 christos
832 1.1 christos PKCS11_CIPHER_ALGORITHM(rc4_40,
833 1.1 christos CKM_RC4,
834 1.1 christos 1,
835 1.1 christos 5,
836 1.1 christos 0,
837 1.1 christos EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH)
838 1.1 christos
839 1.1 christos PKCS11_MD_ALGORITHM(md2, CKM_MD2, 16, 16)
840 1.1 christos #ifdef CKM_MD4 /* non-standard extension */
841 1.1 christos PKCS11_MD_ALGORITHM(md4, CKM_MD4, 16, 64)
842 1.1 christos #else
843 1.1 christos PKCS11_MD_ALGORITHM_UNAVAILABLE(md4)
844 1.1 christos #endif
845 1.1 christos PKCS11_MD_ALGORITHM(md5, CKM_MD5, 16, 64)
846 1.1 christos PKCS11_MD_ALGORITHM(sha1, CKM_SHA_1, 20, 64)
847 1.1 christos PKCS11_MD_ALGORITHM(sha256, CKM_SHA256, 32, 64)
848 1.1 christos PKCS11_MD_ALGORITHM(sha384, CKM_SHA384, 48, 128)
849 1.1 christos PKCS11_MD_ALGORITHM(sha512, CKM_SHA512, 64, 128)
850