1 1.1 christos /* $NetBSD: evp-pkcs11.c,v 1.4 2023/06/19 21:41:43 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 #ifdef CKM_MD4 /* non-standard extension */ 840 1.1 christos PKCS11_MD_ALGORITHM(md4, CKM_MD4, 16, 64) 841 1.1 christos #else 842 1.1 christos PKCS11_MD_ALGORITHM_UNAVAILABLE(md4) 843 1.1 christos #endif 844 1.1 christos PKCS11_MD_ALGORITHM(md5, CKM_MD5, 16, 64) 845 1.1 christos PKCS11_MD_ALGORITHM(sha1, CKM_SHA_1, 20, 64) 846 1.1 christos PKCS11_MD_ALGORITHM(sha256, CKM_SHA256, 32, 64) 847 1.1 christos PKCS11_MD_ALGORITHM(sha384, CKM_SHA384, 48, 128) 848 1.1 christos PKCS11_MD_ALGORITHM(sha512, CKM_SHA512, 64, 128) 849