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