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_lib.h"
18#include "apu.h"
19#include "apu_errno.h"
20
21#include <ctype.h>
22#include <assert.h>
23#include <stdlib.h>
24
25#include "apr_strings.h"
26#include "apr_time.h"
27#include "apr_buckets.h"
28
29#include "apr_crypto_internal.h"
30
31#if APU_HAVE_CRYPTO
32
33#include <openssl/evp.h>
34#include <openssl/engine.h>
35
36#define LOG_PREFIX "apr_crypto_openssl: "
37
38struct apr_crypto_t {
39    apr_pool_t *pool;
40    const apr_crypto_driver_t *provider;
41    apu_err_t *result;
42    apr_array_header_t *keys;
43    apr_crypto_config_t *config;
44    apr_hash_t *types;
45    apr_hash_t *modes;
46};
47
48struct apr_crypto_config_t {
49    ENGINE *engine;
50};
51
52struct apr_crypto_key_t {
53    apr_pool_t *pool;
54    const apr_crypto_driver_t *provider;
55    const apr_crypto_t *f;
56    const EVP_CIPHER * cipher;
57    unsigned char *key;
58    int keyLen;
59    int doPad;
60    int ivSize;
61};
62
63struct apr_crypto_block_t {
64    apr_pool_t *pool;
65    const apr_crypto_driver_t *provider;
66    const apr_crypto_t *f;
67    EVP_CIPHER_CTX cipherCtx;
68    int initialised;
69    int ivSize;
70    int blockSize;
71    int doPad;
72};
73
74static int key_3des_192 = APR_KEY_3DES_192;
75static int key_aes_128 = APR_KEY_AES_128;
76static int key_aes_192 = APR_KEY_AES_192;
77static int key_aes_256 = APR_KEY_AES_256;
78
79static int mode_ecb = APR_MODE_ECB;
80static int mode_cbc = APR_MODE_CBC;
81
82/**
83 * Fetch the most recent error from this driver.
84 */
85static apr_status_t crypto_error(const apu_err_t **result,
86        const apr_crypto_t *f)
87{
88    *result = f->result;
89    return APR_SUCCESS;
90}
91
92/**
93 * Shutdown the crypto library and release resources.
94 */
95static apr_status_t crypto_shutdown(void)
96{
97    ERR_free_strings();
98    EVP_cleanup();
99    ENGINE_cleanup();
100    return APR_SUCCESS;
101}
102
103static apr_status_t crypto_shutdown_helper(void *data)
104{
105    return crypto_shutdown();
106}
107
108/**
109 * Initialise the crypto library and perform one time initialisation.
110 */
111static apr_status_t crypto_init(apr_pool_t *pool, const char *params,
112        const apu_err_t **result)
113{
114    CRYPTO_malloc_init();
115    ERR_load_crypto_strings();
116    /* SSL_load_error_strings(); */
117    OpenSSL_add_all_algorithms();
118    ENGINE_load_builtin_engines();
119    ENGINE_register_all_complete();
120
121    apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper,
122            apr_pool_cleanup_null);
123
124    return APR_SUCCESS;
125}
126
127/**
128 * @brief Clean encryption / decryption context.
129 * @note After cleanup, a context is free to be reused if necessary.
130 * @param ctx The block context to use.
131 * @return Returns APR_ENOTIMPL if not supported.
132 */
133static apr_status_t crypto_block_cleanup(apr_crypto_block_t *ctx)
134{
135
136    if (ctx->initialised) {
137        EVP_CIPHER_CTX_cleanup(&ctx->cipherCtx);
138        ctx->initialised = 0;
139    }
140
141    return APR_SUCCESS;
142
143}
144
145static apr_status_t crypto_block_cleanup_helper(void *data)
146{
147    apr_crypto_block_t *block = (apr_crypto_block_t *) data;
148    return crypto_block_cleanup(block);
149}
150
151/**
152 * @brief Clean encryption / decryption context.
153 * @note After cleanup, a context is free to be reused if necessary.
154 * @param f The context to use.
155 * @return Returns APR_ENOTIMPL if not supported.
156 */
157static apr_status_t crypto_cleanup(apr_crypto_t *f)
158{
159
160    if (f->config->engine) {
161        ENGINE_finish(f->config->engine);
162        ENGINE_free(f->config->engine);
163        f->config->engine = NULL;
164    }
165    return APR_SUCCESS;
166
167}
168
169static apr_status_t crypto_cleanup_helper(void *data)
170{
171    apr_crypto_t *f = (apr_crypto_t *) data;
172    return crypto_cleanup(f);
173}
174
175/**
176 * @brief Create a context for supporting encryption. Keys, certificates,
177 *        algorithms and other parameters will be set per context. More than
178 *        one context can be created at one time. A cleanup will be automatically
179 *        registered with the given pool to guarantee a graceful shutdown.
180 * @param f - context pointer will be written here
181 * @param provider - provider to use
182 * @param params - array of key parameters
183 * @param pool - process pool
184 * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE
185 * if the engine cannot be initialised.
186 */
187static apr_status_t crypto_make(apr_crypto_t **ff,
188        const apr_crypto_driver_t *provider, const char *params,
189        apr_pool_t *pool)
190{
191    apr_crypto_config_t *config = NULL;
192    apr_crypto_t *f = apr_pcalloc(pool, sizeof(apr_crypto_t));
193
194    const char *engine = NULL;
195
196    struct {
197        const char *field;
198        const char *value;
199        int set;
200    } fields[] = {
201        { "engine", NULL, 0 },
202        { NULL, NULL, 0 }
203    };
204    const char *ptr;
205    size_t klen;
206    char **elts = NULL;
207    char *elt;
208    int i = 0, j;
209    apr_status_t status;
210
211    if (params) {
212        if (APR_SUCCESS != (status = apr_tokenize_to_argv(params, &elts, pool))) {
213            return status;
214        }
215        while ((elt = elts[i])) {
216            ptr = strchr(elt, '=');
217            if (ptr) {
218                for (klen = ptr - elt; klen && apr_isspace(elt[klen - 1]); --klen)
219                    ;
220                ptr++;
221            }
222            else {
223                for (klen = strlen(elt); klen && apr_isspace(elt[klen - 1]); --klen)
224                    ;
225            }
226            elt[klen] = 0;
227
228            for (j = 0; fields[j].field != NULL; ++j) {
229                if (!strcasecmp(fields[j].field, elt)) {
230                    fields[j].set = 1;
231                    if (ptr) {
232                        fields[j].value = ptr;
233                    }
234                    break;
235                }
236            }
237
238            i++;
239        }
240        engine = fields[0].value;
241    }
242
243    if (!f) {
244        return APR_ENOMEM;
245    }
246    *ff = f;
247    f->pool = pool;
248    f->provider = provider;
249    config = f->config = apr_pcalloc(pool, sizeof(apr_crypto_config_t));
250    if (!config) {
251        return APR_ENOMEM;
252    }
253
254    f->result = apr_pcalloc(pool, sizeof(apu_err_t));
255    if (!f->result) {
256        return APR_ENOMEM;
257    }
258
259    f->keys = apr_array_make(pool, 10, sizeof(apr_crypto_key_t));
260    if (!f->keys) {
261        return APR_ENOMEM;
262    }
263
264    f->types = apr_hash_make(pool);
265    if (!f->types) {
266        return APR_ENOMEM;
267    }
268    apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_3des_192));
269    apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_aes_128));
270    apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_aes_192));
271    apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_aes_256));
272
273    f->modes = apr_hash_make(pool);
274    if (!f->modes) {
275        return APR_ENOMEM;
276    }
277    apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(mode_ecb));
278    apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(mode_cbc));
279
280    apr_pool_cleanup_register(pool, f, crypto_cleanup_helper,
281            apr_pool_cleanup_null);
282
283    if (engine) {
284        config->engine = ENGINE_by_id(engine);
285        if (!config->engine) {
286            return APR_ENOENGINE;
287        }
288        if (!ENGINE_init(config->engine)) {
289            ENGINE_free(config->engine);
290            config->engine = NULL;
291            return APR_EINITENGINE;
292        }
293    }
294
295    return APR_SUCCESS;
296
297}
298
299/**
300 * @brief Get a hash table of key types, keyed by the name of the type against
301 * an integer pointer constant.
302 *
303 * @param types - hashtable of key types keyed to constants.
304 * @param f - encryption context
305 * @return APR_SUCCESS for success
306 */
307static apr_status_t crypto_get_block_key_types(apr_hash_t **types,
308        const apr_crypto_t *f)
309{
310    *types = f->types;
311    return APR_SUCCESS;
312}
313
314/**
315 * @brief Get a hash table of key modes, keyed by the name of the mode against
316 * an integer pointer constant.
317 *
318 * @param modes - hashtable of key modes keyed to constants.
319 * @param f - encryption context
320 * @return APR_SUCCESS for success
321 */
322static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes,
323        const apr_crypto_t *f)
324{
325    *modes = f->modes;
326    return APR_SUCCESS;
327}
328
329/**
330 * @brief Create a key from the given passphrase. By default, the PBKDF2
331 *        algorithm is used to generate the key from the passphrase. It is expected
332 *        that the same pass phrase will generate the same key, regardless of the
333 *        backend crypto platform used. The key is cleaned up when the context
334 *        is cleaned, and may be reused with multiple encryption or decryption
335 *        operations.
336 * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If
337 *       *key is not NULL, *key must point at a previously created structure.
338 * @param key The key returned, see note.
339 * @param ivSize The size of the initialisation vector will be returned, based
340 *               on whether an IV is relevant for this type of crypto.
341 * @param pass The passphrase to use.
342 * @param passLen The passphrase length in bytes
343 * @param salt The salt to use.
344 * @param saltLen The salt length in bytes
345 * @param type 3DES_192, AES_128, AES_192, AES_256.
346 * @param mode Electronic Code Book / Cipher Block Chaining.
347 * @param doPad Pad if necessary.
348 * @param iterations Iteration count
349 * @param f The context to use.
350 * @param p The pool to use.
351 * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend
352 *         error occurred while generating the key. APR_ENOCIPHER if the type or mode
353 *         is not supported by the particular backend. APR_EKEYTYPE if the key type is
354 *         not known. APR_EPADDING if padding was requested but is not supported.
355 *         APR_ENOTIMPL if not implemented.
356 */
357static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize,
358        const char *pass, apr_size_t passLen, const unsigned char * salt,
359        apr_size_t saltLen, const apr_crypto_block_key_type_e type,
360        const apr_crypto_block_key_mode_e mode, const int doPad,
361        const int iterations, const apr_crypto_t *f, apr_pool_t *p)
362{
363    apr_crypto_key_t *key = *k;
364
365    if (!key) {
366        *k = key = apr_array_push(f->keys);
367    }
368    if (!key) {
369        return APR_ENOMEM;
370    }
371
372    key->f = f;
373    key->provider = f->provider;
374
375    /* determine the cipher to be used */
376    switch (type) {
377
378    case (APR_KEY_3DES_192):
379
380        /* A 3DES key */
381        if (mode == APR_MODE_CBC) {
382            key->cipher = EVP_des_ede3_cbc();
383        }
384        else {
385            key->cipher = EVP_des_ede3_ecb();
386        }
387        break;
388
389    case (APR_KEY_AES_128):
390
391        if (mode == APR_MODE_CBC) {
392            key->cipher = EVP_aes_128_cbc();
393        }
394        else {
395            key->cipher = EVP_aes_128_ecb();
396        }
397        break;
398
399    case (APR_KEY_AES_192):
400
401        if (mode == APR_MODE_CBC) {
402            key->cipher = EVP_aes_192_cbc();
403        }
404        else {
405            key->cipher = EVP_aes_192_ecb();
406        }
407        break;
408
409    case (APR_KEY_AES_256):
410
411        if (mode == APR_MODE_CBC) {
412            key->cipher = EVP_aes_256_cbc();
413        }
414        else {
415            key->cipher = EVP_aes_256_ecb();
416        }
417        break;
418
419    default:
420
421        /* unknown key type, give up */
422        return APR_EKEYTYPE;
423
424    }
425
426    /* find the length of the key we need */
427    key->keyLen = EVP_CIPHER_key_length(key->cipher);
428
429    /* make space for the key */
430    key->key = apr_pcalloc(p, key->keyLen);
431    if (!key->key) {
432        return APR_ENOMEM;
433    }
434    apr_crypto_clear(p, key->key, key->keyLen);
435
436    /* generate the key */
437    if (PKCS5_PBKDF2_HMAC_SHA1(pass, passLen, (unsigned char *) salt, saltLen,
438            iterations, key->keyLen, key->key) == 0) {
439        return APR_ENOKEY;
440    }
441
442    key->doPad = doPad;
443
444    /* note: openssl incorrectly returns non zero IV size values for ECB
445     * algorithms, so work around this by ignoring the IV size.
446     */
447    if (APR_MODE_ECB != mode) {
448        key->ivSize = EVP_CIPHER_iv_length(key->cipher);
449    }
450    if (ivSize) {
451        *ivSize = key->ivSize;
452    }
453
454    return APR_SUCCESS;
455}
456
457/**
458 * @brief Initialise a context for encrypting arbitrary data using the given key.
459 * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
460 *       *ctx is not NULL, *ctx must point at a previously created structure.
461 * @param ctx The block context returned, see note.
462 * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
463 *           an IV will be created at random, in space allocated from the pool.
464 *           If the buffer pointed to is not NULL, the IV in the buffer will be
465 *           used.
466 * @param key The key structure.
467 * @param blockSize The block size of the cipher.
468 * @param p The pool to use.
469 * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
470 *         Returns APR_EINIT if the backend failed to initialise the context. Returns
471 *         APR_ENOTIMPL if not implemented.
472 */
473static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx,
474        const unsigned char **iv, const apr_crypto_key_t *key,
475        apr_size_t *blockSize, apr_pool_t *p)
476{
477    unsigned char *usedIv;
478    apr_crypto_config_t *config = key->f->config;
479    apr_crypto_block_t *block = *ctx;
480    if (!block) {
481        *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
482    }
483    if (!block) {
484        return APR_ENOMEM;
485    }
486    block->f = key->f;
487    block->pool = p;
488    block->provider = key->provider;
489
490    apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
491            apr_pool_cleanup_null);
492
493    /* create a new context for encryption */
494    EVP_CIPHER_CTX_init(&block->cipherCtx);
495    block->initialised = 1;
496
497    /* generate an IV, if necessary */
498    usedIv = NULL;
499    if (key->ivSize) {
500        if (iv == NULL) {
501            return APR_ENOIV;
502        }
503        if (*iv == NULL) {
504            usedIv = apr_pcalloc(p, key->ivSize);
505            if (!usedIv) {
506                return APR_ENOMEM;
507            }
508            apr_crypto_clear(p, usedIv, key->ivSize);
509            if (!((RAND_status() == 1)
510                    && (RAND_bytes(usedIv, key->ivSize) == 1))) {
511                return APR_ENOIV;
512            }
513            *iv = usedIv;
514        }
515        else {
516            usedIv = (unsigned char *) *iv;
517        }
518    }
519
520    /* set up our encryption context */
521#if CRYPTO_OPENSSL_CONST_BUFFERS
522    if (!EVP_EncryptInit_ex(&block->cipherCtx, key->cipher, config->engine,
523            key->key, usedIv)) {
524#else
525        if (!EVP_EncryptInit_ex(&block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) usedIv)) {
526#endif
527        return APR_EINIT;
528    }
529
530    /* Clear up any read padding */
531    if (!EVP_CIPHER_CTX_set_padding(&block->cipherCtx, key->doPad)) {
532        return APR_EPADDING;
533    }
534
535    if (blockSize) {
536        *blockSize = EVP_CIPHER_block_size(key->cipher);
537    }
538
539    return APR_SUCCESS;
540
541}
542
543/**
544 * @brief Encrypt data provided by in, write it to out.
545 * @note The number of bytes written will be written to outlen. If
546 *       out is NULL, outlen will contain the maximum size of the
547 *       buffer needed to hold the data, including any data
548 *       generated by apr_crypto_block_encrypt_finish below. If *out points
549 *       to NULL, a buffer sufficiently large will be created from
550 *       the pool provided. If *out points to a not-NULL value, this
551 *       value will be used as a buffer instead.
552 * @param out Address of a buffer to which data will be written,
553 *        see note.
554 * @param outlen Length of the output will be written here.
555 * @param in Address of the buffer to read.
556 * @param inlen Length of the buffer to read.
557 * @param ctx The block context to use.
558 * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
559 *         not implemented.
560 */
561static apr_status_t crypto_block_encrypt(unsigned char **out,
562        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
563        apr_crypto_block_t *ctx)
564{
565    int outl = *outlen;
566    unsigned char *buffer;
567
568    /* are we after the maximum size of the out buffer? */
569    if (!out) {
570        *outlen = inlen + EVP_MAX_BLOCK_LENGTH;
571        return APR_SUCCESS;
572    }
573
574    /* must we allocate the output buffer from a pool? */
575    if (!*out) {
576        buffer = apr_palloc(ctx->pool, inlen + EVP_MAX_BLOCK_LENGTH);
577        if (!buffer) {
578            return APR_ENOMEM;
579        }
580        apr_crypto_clear(ctx->pool, buffer, inlen + EVP_MAX_BLOCK_LENGTH);
581        *out = buffer;
582    }
583
584#if CRYPT_OPENSSL_CONST_BUFFERS
585    if (!EVP_EncryptUpdate(&ctx->cipherCtx, (*out), &outl, in, inlen)) {
586#else
587    if (!EVP_EncryptUpdate(&ctx->cipherCtx, (*out), &outl,
588            (unsigned char *) in, inlen)) {
589#endif
590        return APR_ECRYPT;
591    }
592    *outlen = outl;
593
594    return APR_SUCCESS;
595
596}
597
598/**
599 * @brief Encrypt final data block, write it to out.
600 * @note If necessary the final block will be written out after being
601 *       padded. Typically the final block will be written to the
602 *       same buffer used by apr_crypto_block_encrypt, offset by the
603 *       number of bytes returned as actually written by the
604 *       apr_crypto_block_encrypt() call. After this call, the context
605 *       is cleaned and can be reused by apr_crypto_block_encrypt_init().
606 * @param out Address of a buffer to which data will be written. This
607 *            buffer must already exist, and is usually the same
608 *            buffer used by apr_evp_crypt(). See note.
609 * @param outlen Length of the output will be written here.
610 * @param ctx The block context to use.
611 * @return APR_ECRYPT if an error occurred.
612 * @return APR_EPADDING if padding was enabled and the block was incorrectly
613 *         formatted.
614 * @return APR_ENOTIMPL if not implemented.
615 */
616static apr_status_t crypto_block_encrypt_finish(unsigned char *out,
617        apr_size_t *outlen, apr_crypto_block_t *ctx)
618{
619    int len = *outlen;
620
621    if (EVP_EncryptFinal_ex(&ctx->cipherCtx, out, &len) == 0) {
622        return APR_EPADDING;
623    }
624    *outlen = len;
625
626    return APR_SUCCESS;
627
628}
629
630/**
631 * @brief Initialise a context for decrypting arbitrary data using the given key.
632 * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
633 *       *ctx is not NULL, *ctx must point at a previously created structure.
634 * @param ctx The block context returned, see note.
635 * @param blockSize The block size of the cipher.
636 * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
637 *           an IV will be created at random, in space allocated from the pool.
638 *           If the buffer is not NULL, the IV in the buffer will be used.
639 * @param key The key structure.
640 * @param p The pool to use.
641 * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
642 *         Returns APR_EINIT if the backend failed to initialise the context. Returns
643 *         APR_ENOTIMPL if not implemented.
644 */
645static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx,
646        apr_size_t *blockSize, const unsigned char *iv,
647        const apr_crypto_key_t *key, apr_pool_t *p)
648{
649    apr_crypto_config_t *config = key->f->config;
650    apr_crypto_block_t *block = *ctx;
651    if (!block) {
652        *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
653    }
654    if (!block) {
655        return APR_ENOMEM;
656    }
657    block->f = key->f;
658    block->pool = p;
659    block->provider = key->provider;
660
661    apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
662            apr_pool_cleanup_null);
663
664    /* create a new context for encryption */
665    EVP_CIPHER_CTX_init(&block->cipherCtx);
666    block->initialised = 1;
667
668    /* generate an IV, if necessary */
669    if (key->ivSize) {
670        if (iv == NULL) {
671            return APR_ENOIV;
672        }
673    }
674
675    /* set up our encryption context */
676#if CRYPTO_OPENSSL_CONST_BUFFERS
677    if (!EVP_DecryptInit_ex(&block->cipherCtx, key->cipher, config->engine,
678            key->key, iv)) {
679#else
680        if (!EVP_DecryptInit_ex(&block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) iv)) {
681#endif
682        return APR_EINIT;
683    }
684
685    /* Clear up any read padding */
686    if (!EVP_CIPHER_CTX_set_padding(&block->cipherCtx, key->doPad)) {
687        return APR_EPADDING;
688    }
689
690    if (blockSize) {
691        *blockSize = EVP_CIPHER_block_size(key->cipher);
692    }
693
694    return APR_SUCCESS;
695
696}
697
698/**
699 * @brief Decrypt data provided by in, write it to out.
700 * @note The number of bytes written will be written to outlen. If
701 *       out is NULL, outlen will contain the maximum size of the
702 *       buffer needed to hold the data, including any data
703 *       generated by apr_crypto_block_decrypt_finish below. If *out points
704 *       to NULL, a buffer sufficiently large will be created from
705 *       the pool provided. If *out points to a not-NULL value, this
706 *       value will be used as a buffer instead.
707 * @param out Address of a buffer to which data will be written,
708 *        see note.
709 * @param outlen Length of the output will be written here.
710 * @param in Address of the buffer to read.
711 * @param inlen Length of the buffer to read.
712 * @param ctx The block context to use.
713 * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
714 *         not implemented.
715 */
716static apr_status_t crypto_block_decrypt(unsigned char **out,
717        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
718        apr_crypto_block_t *ctx)
719{
720    int outl = *outlen;
721    unsigned char *buffer;
722
723    /* are we after the maximum size of the out buffer? */
724    if (!out) {
725        *outlen = inlen + EVP_MAX_BLOCK_LENGTH;
726        return APR_SUCCESS;
727    }
728
729    /* must we allocate the output buffer from a pool? */
730    if (!(*out)) {
731        buffer = apr_palloc(ctx->pool, inlen + EVP_MAX_BLOCK_LENGTH);
732        if (!buffer) {
733            return APR_ENOMEM;
734        }
735        apr_crypto_clear(ctx->pool, buffer, inlen + EVP_MAX_BLOCK_LENGTH);
736        *out = buffer;
737    }
738
739#if CRYPT_OPENSSL_CONST_BUFFERS
740    if (!EVP_DecryptUpdate(&ctx->cipherCtx, *out, &outl, in, inlen)) {
741#else
742    if (!EVP_DecryptUpdate(&ctx->cipherCtx, *out, &outl, (unsigned char *) in,
743            inlen)) {
744#endif
745        return APR_ECRYPT;
746    }
747    *outlen = outl;
748
749    return APR_SUCCESS;
750
751}
752
753/**
754 * @brief Decrypt final data block, write it to out.
755 * @note If necessary the final block will be written out after being
756 *       padded. Typically the final block will be written to the
757 *       same buffer used by apr_crypto_block_decrypt, offset by the
758 *       number of bytes returned as actually written by the
759 *       apr_crypto_block_decrypt() call. After this call, the context
760 *       is cleaned and can be reused by apr_crypto_block_decrypt_init().
761 * @param out Address of a buffer to which data will be written. This
762 *            buffer must already exist, and is usually the same
763 *            buffer used by apr_evp_crypt(). See note.
764 * @param outlen Length of the output will be written here.
765 * @param ctx The block context to use.
766 * @return APR_ECRYPT if an error occurred.
767 * @return APR_EPADDING if padding was enabled and the block was incorrectly
768 *         formatted.
769 * @return APR_ENOTIMPL if not implemented.
770 */
771static apr_status_t crypto_block_decrypt_finish(unsigned char *out,
772        apr_size_t *outlen, apr_crypto_block_t *ctx)
773{
774
775    int len = *outlen;
776
777    if (EVP_DecryptFinal_ex(&ctx->cipherCtx, out, &len) == 0) {
778        return APR_EPADDING;
779    }
780    *outlen = len;
781
782    return APR_SUCCESS;
783
784}
785
786/**
787 * OpenSSL module.
788 */
789APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_openssl_driver = {
790    "openssl", crypto_init, crypto_make, crypto_get_block_key_types,
791    crypto_get_block_key_modes, crypto_passphrase,
792    crypto_block_encrypt_init, crypto_block_encrypt,
793    crypto_block_encrypt_finish, crypto_block_decrypt_init,
794    crypto_block_decrypt, crypto_block_decrypt_finish,
795    crypto_block_cleanup, crypto_cleanup, crypto_shutdown, crypto_error
796};
797
798#endif
799