1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr.h" 18#include "apr_lib.h" 19#include "apu.h" 20#include "apu_errno.h" 21 22#include <ctype.h> 23#include <assert.h> 24#include <stdlib.h> 25 26#include "apr_strings.h" 27#include "apr_time.h" 28#include "apr_buckets.h" 29#include "apr_random.h" 30 31#include "apr_crypto_internal.h" 32 33#if APU_HAVE_CRYPTO 34 35#include <CommonCrypto/CommonCrypto.h> 36 37#define LOG_PREFIX "apr_crypto_commoncrypto: " 38 39struct apr_crypto_t 40{ 41 apr_pool_t *pool; 42 const apr_crypto_driver_t *provider; 43 apu_err_t *result; 44 apr_hash_t *types; 45 apr_hash_t *modes; 46 apr_random_t *rng; 47}; 48 49struct apr_crypto_key_t 50{ 51 apr_pool_t *pool; 52 const apr_crypto_driver_t *provider; 53 const apr_crypto_t *f; 54 CCAlgorithm algorithm; 55 CCOptions options; 56 unsigned char *key; 57 int keyLen; 58 int ivSize; 59 apr_size_t blockSize; 60}; 61 62struct apr_crypto_block_t 63{ 64 apr_pool_t *pool; 65 const apr_crypto_driver_t *provider; 66 const apr_crypto_t *f; 67 const apr_crypto_key_t *key; 68 CCCryptorRef ref; 69}; 70 71static struct apr_crypto_block_key_type_t key_types[] = 72{ 73{ APR_KEY_3DES_192, 24, 8, 8 }, 74{ APR_KEY_AES_128, 16, 16, 16 }, 75{ APR_KEY_AES_192, 24, 16, 16 }, 76{ APR_KEY_AES_256, 32, 16, 16 } }; 77 78static struct apr_crypto_block_key_mode_t key_modes[] = 79{ 80{ APR_MODE_ECB }, 81{ APR_MODE_CBC } }; 82 83/** 84 * Fetch the most recent error from this driver. 85 */ 86static apr_status_t crypto_error(const apu_err_t **result, 87 const apr_crypto_t *f) 88{ 89 *result = f->result; 90 return APR_SUCCESS; 91} 92 93/** 94 * Shutdown the crypto library and release resources. 95 */ 96static apr_status_t crypto_shutdown(void) 97{ 98 return APR_SUCCESS; 99} 100 101static apr_status_t crypto_shutdown_helper(void *data) 102{ 103 return crypto_shutdown(); 104} 105 106/** 107 * Initialise the crypto library and perform one time initialisation. 108 */ 109static apr_status_t crypto_init(apr_pool_t *pool, const char *params, 110 const apu_err_t **result) 111{ 112 113 apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper, 114 apr_pool_cleanup_null); 115 116 return APR_SUCCESS; 117} 118 119/** 120 * @brief Clean encryption / decryption context. 121 * @note After cleanup, a context is free to be reused if necessary. 122 * @param ctx The block context to use. 123 * @return Returns APR_ENOTIMPL if not supported. 124 */ 125static apr_status_t crypto_block_cleanup(apr_crypto_block_t *ctx) 126{ 127 128 if (ctx->ref) { 129 CCCryptorRelease(ctx->ref); 130 ctx->ref = NULL; 131 } 132 133 return APR_SUCCESS; 134 135} 136 137static apr_status_t crypto_block_cleanup_helper(void *data) 138{ 139 apr_crypto_block_t *block = (apr_crypto_block_t *) data; 140 return crypto_block_cleanup(block); 141} 142 143/** 144 * @brief Clean encryption / decryption context. 145 * @note After cleanup, a context is free to be reused if necessary. 146 * @param f The context to use. 147 * @return Returns APR_ENOTIMPL if not supported. 148 */ 149static apr_status_t crypto_cleanup(apr_crypto_t *f) 150{ 151 152 return APR_SUCCESS; 153 154} 155 156static apr_status_t crypto_cleanup_helper(void *data) 157{ 158 apr_crypto_t *f = (apr_crypto_t *) data; 159 return crypto_cleanup(f); 160} 161 162/** 163 * @brief Create a context for supporting encryption. Keys, certificates, 164 * algorithms and other parameters will be set per context. More than 165 * one context can be created at one time. A cleanup will be automatically 166 * registered with the given pool to guarantee a graceful shutdown. 167 * @param f - context pointer will be written here 168 * @param provider - provider to use 169 * @param params - array of key parameters 170 * @param pool - process pool 171 * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE 172 * if the engine cannot be initialised. 173 */ 174static apr_status_t crypto_make(apr_crypto_t **ff, 175 const apr_crypto_driver_t *provider, const char *params, 176 apr_pool_t *pool) 177{ 178 apr_crypto_t *f = apr_pcalloc(pool, sizeof(apr_crypto_t)); 179 apr_status_t rv; 180 181 if (!f) { 182 return APR_ENOMEM; 183 } 184 *ff = f; 185 f->pool = pool; 186 f->provider = provider; 187 188 /* seed the secure random number generator */ 189 f->rng = apr_random_standard_new(pool); 190 if (!f->rng) { 191 return APR_ENOMEM; 192 } 193 do { 194 unsigned char seed[8]; 195 rv = apr_generate_random_bytes(seed, sizeof(seed)); 196 if (rv != APR_SUCCESS) { 197 return rv; 198 } 199 apr_random_add_entropy(f->rng, seed, sizeof(seed)); 200 rv = apr_random_secure_ready(f->rng); 201 } while (rv == APR_ENOTENOUGHENTROPY); 202 203 f->result = apr_pcalloc(pool, sizeof(apu_err_t)); 204 if (!f->result) { 205 return APR_ENOMEM; 206 } 207 208 f->types = apr_hash_make(pool); 209 if (!f->types) { 210 return APR_ENOMEM; 211 } 212 apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_types[0])); 213 apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_types[1])); 214 apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_types[2])); 215 apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_types[3])); 216 217 f->modes = apr_hash_make(pool); 218 if (!f->modes) { 219 return APR_ENOMEM; 220 } 221 apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(key_modes[0])); 222 apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(key_modes[1])); 223 224 apr_pool_cleanup_register(pool, f, crypto_cleanup_helper, 225 apr_pool_cleanup_null); 226 227 return APR_SUCCESS; 228 229} 230 231/** 232 * @brief Get a hash table of key types, keyed by the name of the type against 233 * a pointer to apr_crypto_block_key_type_t. 234 * 235 * @param types - hashtable of key types keyed to constants. 236 * @param f - encryption context 237 * @return APR_SUCCESS for success 238 */ 239static apr_status_t crypto_get_block_key_types(apr_hash_t **types, 240 const apr_crypto_t *f) 241{ 242 *types = f->types; 243 return APR_SUCCESS; 244} 245 246/** 247 * @brief Get a hash table of key modes, keyed by the name of the mode against 248 * a pointer to apr_crypto_block_key_mode_t. 249 * 250 * @param modes - hashtable of key modes keyed to constants. 251 * @param f - encryption context 252 * @return APR_SUCCESS for success 253 */ 254static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes, 255 const apr_crypto_t *f) 256{ 257 *modes = f->modes; 258 return APR_SUCCESS; 259} 260 261/* 262 * Work out which mechanism to use. 263 */ 264static apr_status_t crypto_cipher_mechanism(apr_crypto_key_t *key, 265 const apr_crypto_block_key_type_e type, 266 const apr_crypto_block_key_mode_e mode, const int doPad, apr_pool_t *p) 267{ 268 /* handle padding */ 269 key->options = doPad ? kCCOptionPKCS7Padding : 0; 270 271 /* determine the algorithm to be used */ 272 switch (type) { 273 274 case (APR_KEY_3DES_192): 275 276 /* A 3DES key */ 277 if (mode == APR_MODE_CBC) { 278 key->algorithm = kCCAlgorithm3DES; 279 key->keyLen = kCCKeySize3DES; 280 key->ivSize = kCCBlockSize3DES; 281 key->blockSize = kCCBlockSize3DES; 282 } 283 else { 284 key->algorithm = kCCAlgorithm3DES; 285 key->options += kCCOptionECBMode; 286 key->keyLen = kCCKeySize3DES; 287 key->ivSize = 0; 288 key->blockSize = kCCBlockSize3DES; 289 } 290 break; 291 292 case (APR_KEY_AES_128): 293 294 if (mode == APR_MODE_CBC) { 295 key->algorithm = kCCAlgorithmAES128; 296 key->keyLen = kCCKeySizeAES128; 297 key->ivSize = kCCBlockSizeAES128; 298 key->blockSize = kCCBlockSizeAES128; 299 } 300 else { 301 key->algorithm = kCCAlgorithmAES128; 302 key->options += kCCOptionECBMode; 303 key->keyLen = kCCKeySizeAES128; 304 key->ivSize = 0; 305 key->blockSize = kCCBlockSizeAES128; 306 } 307 break; 308 309 case (APR_KEY_AES_192): 310 311 if (mode == APR_MODE_CBC) { 312 key->algorithm = kCCAlgorithmAES128; 313 key->keyLen = kCCKeySizeAES192; 314 key->ivSize = kCCBlockSizeAES128; 315 key->blockSize = kCCBlockSizeAES128; 316 } 317 else { 318 key->algorithm = kCCAlgorithmAES128; 319 key->options += kCCOptionECBMode; 320 key->keyLen = kCCKeySizeAES192; 321 key->ivSize = 0; 322 key->blockSize = kCCBlockSizeAES128; 323 } 324 break; 325 326 case (APR_KEY_AES_256): 327 328 if (mode == APR_MODE_CBC) { 329 key->algorithm = kCCAlgorithmAES128; 330 key->keyLen = kCCKeySizeAES256; 331 key->ivSize = kCCBlockSizeAES128; 332 key->blockSize = kCCBlockSizeAES128; 333 } 334 else { 335 key->algorithm = kCCAlgorithmAES128; 336 key->options += kCCOptionECBMode; 337 key->keyLen = kCCKeySizeAES256; 338 key->ivSize = 0; 339 key->blockSize = kCCBlockSizeAES128; 340 } 341 break; 342 343 default: 344 345 /* TODO: Support CAST, Blowfish */ 346 347 /* unknown key type, give up */ 348 return APR_EKEYTYPE; 349 350 } 351 352 /* make space for the key */ 353 key->key = apr_palloc(p, key->keyLen); 354 if (!key->key) { 355 return APR_ENOMEM; 356 } 357 apr_crypto_clear(p, key->key, key->keyLen); 358 359 return APR_SUCCESS; 360} 361 362/** 363 * @brief Create a key from the provided secret or passphrase. The key is cleaned 364 * up when the context is cleaned, and may be reused with multiple encryption 365 * or decryption operations. 366 * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If 367 * *key is not NULL, *key must point at a previously created structure. 368 * @param key The key returned, see note. 369 * @param rec The key record, from which the key will be derived. 370 * @param f The context to use. 371 * @param p The pool to use. 372 * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend 373 * error occurred while generating the key. APR_ENOCIPHER if the type or mode 374 * is not supported by the particular backend. APR_EKEYTYPE if the key type is 375 * not known. APR_EPADDING if padding was requested but is not supported. 376 * APR_ENOTIMPL if not implemented. 377 */ 378static apr_status_t crypto_key(apr_crypto_key_t **k, 379 const apr_crypto_key_rec_t *rec, const apr_crypto_t *f, apr_pool_t *p) 380{ 381 apr_status_t rv; 382 apr_crypto_key_t *key = *k; 383 384 if (!key) { 385 *k = key = apr_pcalloc(p, sizeof *key); 386 } 387 if (!key) { 388 return APR_ENOMEM; 389 } 390 391 key->f = f; 392 key->provider = f->provider; 393 394 /* decide on what cipher mechanism we will be using */ 395 rv = crypto_cipher_mechanism(key, rec->type, rec->mode, rec->pad, p); 396 if (APR_SUCCESS != rv) { 397 return rv; 398 } 399 400 switch (rec->ktype) { 401 402 case APR_CRYPTO_KTYPE_PASSPHRASE: { 403 404 /* generate the key */ 405 if ((f->result->rc = CCKeyDerivationPBKDF(kCCPBKDF2, 406 rec->k.passphrase.pass, rec->k.passphrase.passLen, 407 rec->k.passphrase.salt, rec->k.passphrase.saltLen, 408 kCCPRFHmacAlgSHA1, rec->k.passphrase.iterations, key->key, 409 key->keyLen)) == kCCParamError) { 410 return APR_ENOKEY; 411 } 412 413 break; 414 } 415 416 case APR_CRYPTO_KTYPE_SECRET: { 417 418 /* sanity check - key correct size? */ 419 if (rec->k.secret.secretLen != key->keyLen) { 420 return APR_EKEYLENGTH; 421 } 422 423 /* copy the key */ 424 memcpy(key->key, rec->k.secret.secret, rec->k.secret.secretLen); 425 426 break; 427 } 428 429 default: { 430 431 return APR_ENOKEY; 432 433 } 434 } 435 436 return APR_SUCCESS; 437} 438 439/** 440 * @brief Create a key from the given passphrase. By default, the PBKDF2 441 * algorithm is used to generate the key from the passphrase. It is expected 442 * that the same pass phrase will generate the same key, regardless of the 443 * backend crypto platform used. The key is cleaned up when the context 444 * is cleaned, and may be reused with multiple encryption or decryption 445 * operations. 446 * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If 447 * *key is not NULL, *key must point at a previously created structure. 448 * @param key The key returned, see note. 449 * @param ivSize The size of the initialisation vector will be returned, based 450 * on whether an IV is relevant for this type of crypto. 451 * @param pass The passphrase to use. 452 * @param passLen The passphrase length in bytes 453 * @param salt The salt to use. 454 * @param saltLen The salt length in bytes 455 * @param type 3DES_192, AES_128, AES_192, AES_256. 456 * @param mode Electronic Code Book / Cipher Block Chaining. 457 * @param doPad Pad if necessary. 458 * @param iterations Iteration count 459 * @param f The context to use. 460 * @param p The pool to use. 461 * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend 462 * error occurred while generating the key. APR_ENOCIPHER if the type or mode 463 * is not supported by the particular backend. APR_EKEYTYPE if the key type is 464 * not known. APR_EPADDING if padding was requested but is not supported. 465 * APR_ENOTIMPL if not implemented. 466 */ 467static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, 468 const char *pass, apr_size_t passLen, const unsigned char * salt, 469 apr_size_t saltLen, const apr_crypto_block_key_type_e type, 470 const apr_crypto_block_key_mode_e mode, const int doPad, 471 const int iterations, const apr_crypto_t *f, apr_pool_t *p) 472{ 473 apr_status_t rv; 474 apr_crypto_key_t *key = *k; 475 476 if (!key) { 477 *k = key = apr_pcalloc(p, sizeof *key); 478 if (!key) { 479 return APR_ENOMEM; 480 } 481 } 482 483 key->f = f; 484 key->provider = f->provider; 485 486 /* decide on what cipher mechanism we will be using */ 487 rv = crypto_cipher_mechanism(key, type, mode, doPad, p); 488 if (APR_SUCCESS != rv) { 489 return rv; 490 } 491 492 /* generate the key */ 493 if ((f->result->rc = CCKeyDerivationPBKDF(kCCPBKDF2, pass, passLen, salt, 494 saltLen, kCCPRFHmacAlgSHA1, iterations, key->key, key->keyLen)) 495 == kCCParamError) { 496 return APR_ENOKEY; 497 } 498 499 if (ivSize) { 500 *ivSize = key->ivSize; 501 } 502 503 return APR_SUCCESS; 504} 505 506/** 507 * @brief Initialise a context for encrypting arbitrary data using the given key. 508 * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If 509 * *ctx is not NULL, *ctx must point at a previously created structure. 510 * @param ctx The block context returned, see note. 511 * @param iv Optional initialisation vector. If the buffer pointed to is NULL, 512 * an IV will be created at random, in space allocated from the pool. 513 * If the buffer pointed to is not NULL, the IV in the buffer will be 514 * used. 515 * @param key The key structure. 516 * @param blockSize The block size of the cipher. 517 * @param p The pool to use. 518 * @return Returns APR_ENOIV if an initialisation vector is required but not specified. 519 * Returns APR_EINIT if the backend failed to initialise the context. Returns 520 * APR_ENOTIMPL if not implemented. 521 */ 522static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx, 523 const unsigned char **iv, const apr_crypto_key_t *key, 524 apr_size_t *blockSize, apr_pool_t *p) 525{ 526 unsigned char *usedIv; 527 apr_crypto_block_t *block = *ctx; 528 if (!block) { 529 *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t)); 530 } 531 if (!block) { 532 return APR_ENOMEM; 533 } 534 block->f = key->f; 535 block->pool = p; 536 block->provider = key->provider; 537 block->key = key; 538 539 apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper, 540 apr_pool_cleanup_null); 541 542 /* generate an IV, if necessary */ 543 usedIv = NULL; 544 if (key->ivSize) { 545 if (iv == NULL) { 546 return APR_ENOIV; 547 } 548 if (*iv == NULL) { 549 apr_status_t status; 550 usedIv = apr_pcalloc(p, key->ivSize); 551 if (!usedIv) { 552 return APR_ENOMEM; 553 } 554 apr_crypto_clear(p, usedIv, key->ivSize); 555 status = apr_random_secure_bytes(block->f->rng, usedIv, 556 key->ivSize); 557 if (APR_SUCCESS != status) { 558 return status; 559 } 560 *iv = usedIv; 561 } 562 else { 563 usedIv = (unsigned char *) *iv; 564 } 565 } 566 567 /* create a new context for encryption */ 568 switch ((block->f->result->rc = CCCryptorCreate(kCCEncrypt, key->algorithm, 569 key->options, key->key, key->keyLen, usedIv, &block->ref))) { 570 case kCCSuccess: { 571 break; 572 } 573 case kCCParamError: { 574 return APR_EINIT; 575 } 576 case kCCMemoryFailure: { 577 return APR_ENOMEM; 578 } 579 case kCCAlignmentError: { 580 return APR_EPADDING; 581 } 582 case kCCUnimplemented: { 583 return APR_ENOTIMPL; 584 } 585 default: { 586 return APR_EINIT; 587 } 588 } 589 590 if (blockSize) { 591 *blockSize = key->blockSize; 592 } 593 594 return APR_SUCCESS; 595 596} 597 598/** 599 * @brief Encrypt data provided by in, write it to out. 600 * @note The number of bytes written will be written to outlen. If 601 * out is NULL, outlen will contain the maximum size of the 602 * buffer needed to hold the data, including any data 603 * generated by apr_crypto_block_encrypt_finish below. If *out points 604 * to NULL, a buffer sufficiently large will be created from 605 * the pool provided. If *out points to a not-NULL value, this 606 * value will be used as a buffer instead. 607 * @param out Address of a buffer to which data will be written, 608 * see note. 609 * @param outlen Length of the output will be written here. 610 * @param in Address of the buffer to read. 611 * @param inlen Length of the buffer to read. 612 * @param ctx The block context to use. 613 * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if 614 * not implemented. 615 */ 616static apr_status_t crypto_block_encrypt(unsigned char **out, 617 apr_size_t *outlen, const unsigned char *in, apr_size_t inlen, 618 apr_crypto_block_t *ctx) 619{ 620 apr_size_t outl = *outlen; 621 unsigned char *buffer; 622 623 /* are we after the maximum size of the out buffer? */ 624 if (!out) { 625 *outlen = CCCryptorGetOutputLength(ctx->ref, inlen, 1); 626 return APR_SUCCESS; 627 } 628 629 /* must we allocate the output buffer from a pool? */ 630 if (!*out) { 631 outl = CCCryptorGetOutputLength(ctx->ref, inlen, 1); 632 buffer = apr_palloc(ctx->pool, outl); 633 if (!buffer) { 634 return APR_ENOMEM; 635 } 636 apr_crypto_clear(ctx->pool, buffer, outl); 637 *out = buffer; 638 } 639 640 switch ((ctx->f->result->rc = CCCryptorUpdate(ctx->ref, in, inlen, (*out), 641 outl, &outl))) { 642 case kCCSuccess: { 643 break; 644 } 645 case kCCBufferTooSmall: { 646 return APR_ENOSPACE; 647 } 648 default: { 649 return APR_ECRYPT; 650 } 651 } 652 *outlen = outl; 653 654 return APR_SUCCESS; 655 656} 657 658/** 659 * @brief Encrypt final data block, write it to out. 660 * @note If necessary the final block will be written out after being 661 * padded. Typically the final block will be written to the 662 * same buffer used by apr_crypto_block_encrypt, offset by the 663 * number of bytes returned as actually written by the 664 * apr_crypto_block_encrypt() call. After this call, the context 665 * is cleaned and can be reused by apr_crypto_block_encrypt_init(). 666 * @param out Address of a buffer to which data will be written. This 667 * buffer must already exist, and is usually the same 668 * buffer used by apr_evp_crypt(). See note. 669 * @param outlen Length of the output will be written here. 670 * @param ctx The block context to use. 671 * @return APR_ECRYPT if an error occurred. 672 * @return APR_EPADDING if padding was enabled and the block was incorrectly 673 * formatted. 674 * @return APR_ENOTIMPL if not implemented. 675 */ 676static apr_status_t crypto_block_encrypt_finish(unsigned char *out, 677 apr_size_t *outlen, apr_crypto_block_t *ctx) 678{ 679 apr_size_t len = *outlen; 680 681 ctx->f->result->rc = CCCryptorFinal(ctx->ref, out, 682 CCCryptorGetOutputLength(ctx->ref, 0, 1), &len); 683 684 /* always clean up */ 685 crypto_block_cleanup(ctx); 686 687 switch (ctx->f->result->rc) { 688 case kCCSuccess: { 689 break; 690 } 691 case kCCBufferTooSmall: { 692 return APR_ENOSPACE; 693 } 694 case kCCAlignmentError: { 695 return APR_EPADDING; 696 } 697 case kCCDecodeError: { 698 return APR_ECRYPT; 699 } 700 default: { 701 return APR_ECRYPT; 702 } 703 } 704 *outlen = len; 705 706 return APR_SUCCESS; 707 708} 709 710/** 711 * @brief Initialise a context for decrypting arbitrary data using the given key. 712 * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If 713 * *ctx is not NULL, *ctx must point at a previously created structure. 714 * @param ctx The block context returned, see note. 715 * @param blockSize The block size of the cipher. 716 * @param iv Optional initialisation vector. If the buffer pointed to is NULL, 717 * an IV will be created at random, in space allocated from the pool. 718 * If the buffer is not NULL, the IV in the buffer will be used. 719 * @param key The key structure. 720 * @param p The pool to use. 721 * @return Returns APR_ENOIV if an initialisation vector is required but not specified. 722 * Returns APR_EINIT if the backend failed to initialise the context. Returns 723 * APR_ENOTIMPL if not implemented. 724 */ 725static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx, 726 apr_size_t *blockSize, const unsigned char *iv, 727 const apr_crypto_key_t *key, apr_pool_t *p) 728{ 729 apr_crypto_block_t *block = *ctx; 730 if (!block) { 731 *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t)); 732 } 733 if (!block) { 734 return APR_ENOMEM; 735 } 736 block->f = key->f; 737 block->pool = p; 738 block->provider = key->provider; 739 740 apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper, 741 apr_pool_cleanup_null); 742 743 /* generate an IV, if necessary */ 744 if (key->ivSize) { 745 if (iv == NULL) { 746 return APR_ENOIV; 747 } 748 } 749 750 /* create a new context for decryption */ 751 switch ((block->f->result->rc = CCCryptorCreate(kCCDecrypt, key->algorithm, 752 key->options, key->key, key->keyLen, iv, &block->ref))) { 753 case kCCSuccess: { 754 break; 755 } 756 case kCCParamError: { 757 return APR_EINIT; 758 } 759 case kCCMemoryFailure: { 760 return APR_ENOMEM; 761 } 762 case kCCAlignmentError: { 763 return APR_EPADDING; 764 } 765 case kCCUnimplemented: { 766 return APR_ENOTIMPL; 767 } 768 default: { 769 return APR_EINIT; 770 } 771 } 772 773 if (blockSize) { 774 *blockSize = key->blockSize; 775 } 776 777 return APR_SUCCESS; 778 779} 780 781/** 782 * @brief Decrypt data provided by in, write it to out. 783 * @note The number of bytes written will be written to outlen. If 784 * out is NULL, outlen will contain the maximum size of the 785 * buffer needed to hold the data, including any data 786 * generated by apr_crypto_block_decrypt_finish below. If *out points 787 * to NULL, a buffer sufficiently large will be created from 788 * the pool provided. If *out points to a not-NULL value, this 789 * value will be used as a buffer instead. 790 * @param out Address of a buffer to which data will be written, 791 * see note. 792 * @param outlen Length of the output will be written here. 793 * @param in Address of the buffer to read. 794 * @param inlen Length of the buffer to read. 795 * @param ctx The block context to use. 796 * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if 797 * not implemented. 798 */ 799static apr_status_t crypto_block_decrypt(unsigned char **out, 800 apr_size_t *outlen, const unsigned char *in, apr_size_t inlen, 801 apr_crypto_block_t *ctx) 802{ 803 apr_size_t outl = *outlen; 804 unsigned char *buffer; 805 806 /* are we after the maximum size of the out buffer? */ 807 if (!out) { 808 *outlen = CCCryptorGetOutputLength(ctx->ref, inlen, 1); 809 return APR_SUCCESS; 810 } 811 812 /* must we allocate the output buffer from a pool? */ 813 if (!*out) { 814 outl = CCCryptorGetOutputLength(ctx->ref, inlen, 1); 815 buffer = apr_palloc(ctx->pool, outl); 816 if (!buffer) { 817 return APR_ENOMEM; 818 } 819 apr_crypto_clear(ctx->pool, buffer, outl); 820 *out = buffer; 821 } 822 823 switch ((ctx->f->result->rc = CCCryptorUpdate(ctx->ref, in, inlen, (*out), 824 outl, &outl))) { 825 case kCCSuccess: { 826 break; 827 } 828 case kCCBufferTooSmall: { 829 return APR_ENOSPACE; 830 } 831 default: { 832 return APR_ECRYPT; 833 } 834 } 835 *outlen = outl; 836 837 return APR_SUCCESS; 838 839} 840 841/** 842 * @brief Decrypt final data block, write it to out. 843 * @note If necessary the final block will be written out after being 844 * padded. Typically the final block will be written to the 845 * same buffer used by apr_crypto_block_decrypt, offset by the 846 * number of bytes returned as actually written by the 847 * apr_crypto_block_decrypt() call. After this call, the context 848 * is cleaned and can be reused by apr_crypto_block_decrypt_init(). 849 * @param out Address of a buffer to which data will be written. This 850 * buffer must already exist, and is usually the same 851 * buffer used by apr_evp_crypt(). See note. 852 * @param outlen Length of the output will be written here. 853 * @param ctx The block context to use. 854 * @return APR_ECRYPT if an error occurred. 855 * @return APR_EPADDING if padding was enabled and the block was incorrectly 856 * formatted. 857 * @return APR_ENOTIMPL if not implemented. 858 */ 859static apr_status_t crypto_block_decrypt_finish(unsigned char *out, 860 apr_size_t *outlen, apr_crypto_block_t *ctx) 861{ 862 apr_size_t len = *outlen; 863 864 ctx->f->result->rc = CCCryptorFinal(ctx->ref, out, 865 CCCryptorGetOutputLength(ctx->ref, 0, 1), &len); 866 867 /* always clean up */ 868 crypto_block_cleanup(ctx); 869 870 switch (ctx->f->result->rc) { 871 case kCCSuccess: { 872 break; 873 } 874 case kCCBufferTooSmall: { 875 return APR_ENOSPACE; 876 } 877 case kCCAlignmentError: { 878 return APR_EPADDING; 879 } 880 case kCCDecodeError: { 881 return APR_ECRYPT; 882 } 883 default: { 884 return APR_ECRYPT; 885 } 886 } 887 *outlen = len; 888 889 return APR_SUCCESS; 890 891} 892 893/** 894 * OSX Common Crypto module. 895 */ 896APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_commoncrypto_driver = 897{ 898 "commoncrypto", crypto_init, crypto_make, crypto_get_block_key_types, 899 crypto_get_block_key_modes, crypto_passphrase, 900 crypto_block_encrypt_init, crypto_block_encrypt, 901 crypto_block_encrypt_finish, crypto_block_decrypt_init, 902 crypto_block_decrypt, crypto_block_decrypt_finish, crypto_block_cleanup, 903 crypto_cleanup, crypto_shutdown, crypto_error, crypto_key 904}; 905 906#endif 907