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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "apu_errno.h"
26 #include "apr_strings.h"
28 #include "apr_buckets.h"
29 #include "apr_random.h"
31 #include "apr_crypto_internal.h"
35 #include <CommonCrypto/CommonCrypto.h>
37 #define LOG_PREFIX "apr_crypto_commoncrypto: "
42 const apr_crypto_driver_t *provider;
49 struct apr_crypto_key_t
52 const apr_crypto_driver_t *provider;
53 const apr_crypto_t *f;
54 CCAlgorithm algorithm;
62 struct apr_crypto_block_t
65 const apr_crypto_driver_t *provider;
66 const apr_crypto_t *f;
67 const apr_crypto_key_t *key;
71 static struct apr_crypto_block_key_type_t key_types[] =
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 } };
78 static struct apr_crypto_block_key_mode_t key_modes[] =
84 * Fetch the most recent error from this driver.
86 static apr_status_t crypto_error(const apu_err_t **result,
87 const apr_crypto_t *f)
94 * Shutdown the crypto library and release resources.
96 static apr_status_t crypto_shutdown(void)
101 static apr_status_t crypto_shutdown_helper(void *data)
103 return crypto_shutdown();
107 * Initialise the crypto library and perform one time initialisation.
109 static apr_status_t crypto_init(apr_pool_t *pool, const char *params,
110 const apu_err_t **result)
113 apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper,
114 apr_pool_cleanup_null);
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.
125 static apr_status_t crypto_block_cleanup(apr_crypto_block_t *ctx)
129 CCCryptorRelease(ctx->ref);
137 static apr_status_t crypto_block_cleanup_helper(void *data)
139 apr_crypto_block_t *block = (apr_crypto_block_t *) data;
140 return crypto_block_cleanup(block);
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.
149 static apr_status_t crypto_cleanup(apr_crypto_t *f)
156 static apr_status_t crypto_cleanup_helper(void *data)
158 apr_crypto_t *f = (apr_crypto_t *) data;
159 return crypto_cleanup(f);
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.
174 static apr_status_t crypto_make(apr_crypto_t **ff,
175 const apr_crypto_driver_t *provider, const char *params,
178 apr_crypto_t *f = apr_pcalloc(pool, sizeof(apr_crypto_t));
186 f->provider = provider;
188 /* seed the secure random number generator */
189 f->rng = apr_random_standard_new(pool);
194 unsigned char seed[8];
195 rv = apr_generate_random_bytes(seed, sizeof(seed));
196 if (rv != APR_SUCCESS) {
199 apr_random_add_entropy(f->rng, seed, sizeof(seed));
200 rv = apr_random_secure_ready(f->rng);
201 } while (rv == APR_ENOTENOUGHENTROPY);
203 f->result = apr_pcalloc(pool, sizeof(apu_err_t));
208 f->types = apr_hash_make(pool);
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]));
217 f->modes = apr_hash_make(pool);
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]));
224 apr_pool_cleanup_register(pool, f, crypto_cleanup_helper,
225 apr_pool_cleanup_null);
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.
235 * @param types - hashtable of key types keyed to constants.
236 * @param f - encryption context
237 * @return APR_SUCCESS for success
239 static apr_status_t crypto_get_block_key_types(apr_hash_t **types,
240 const apr_crypto_t *f)
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.
250 * @param modes - hashtable of key modes keyed to constants.
251 * @param f - encryption context
252 * @return APR_SUCCESS for success
254 static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes,
255 const apr_crypto_t *f)
262 * Work out which mechanism to use.
264 static 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)
269 key->options = doPad ? kCCOptionPKCS7Padding : 0;
271 /* determine the algorithm to be used */
274 case (APR_KEY_3DES_192):
277 if (mode == APR_MODE_CBC) {
278 key->algorithm = kCCAlgorithm3DES;
279 key->keyLen = kCCKeySize3DES;
280 key->ivSize = kCCBlockSize3DES;
281 key->blockSize = kCCBlockSize3DES;
284 key->algorithm = kCCAlgorithm3DES;
285 key->options += kCCOptionECBMode;
286 key->keyLen = kCCKeySize3DES;
288 key->blockSize = kCCBlockSize3DES;
292 case (APR_KEY_AES_128):
294 if (mode == APR_MODE_CBC) {
295 key->algorithm = kCCAlgorithmAES128;
296 key->keyLen = kCCKeySizeAES128;
297 key->ivSize = kCCBlockSizeAES128;
298 key->blockSize = kCCBlockSizeAES128;
301 key->algorithm = kCCAlgorithmAES128;
302 key->options += kCCOptionECBMode;
303 key->keyLen = kCCKeySizeAES128;
305 key->blockSize = kCCBlockSizeAES128;
309 case (APR_KEY_AES_192):
311 if (mode == APR_MODE_CBC) {
312 key->algorithm = kCCAlgorithmAES128;
313 key->keyLen = kCCKeySizeAES192;
314 key->ivSize = kCCBlockSizeAES128;
315 key->blockSize = kCCBlockSizeAES128;
318 key->algorithm = kCCAlgorithmAES128;
319 key->options += kCCOptionECBMode;
320 key->keyLen = kCCKeySizeAES192;
322 key->blockSize = kCCBlockSizeAES128;
326 case (APR_KEY_AES_256):
328 if (mode == APR_MODE_CBC) {
329 key->algorithm = kCCAlgorithmAES128;
330 key->keyLen = kCCKeySizeAES256;
331 key->ivSize = kCCBlockSizeAES128;
332 key->blockSize = kCCBlockSizeAES128;
335 key->algorithm = kCCAlgorithmAES128;
336 key->options += kCCOptionECBMode;
337 key->keyLen = kCCKeySizeAES256;
339 key->blockSize = kCCBlockSizeAES128;
345 /* TODO: Support CAST, Blowfish */
347 /* unknown key type, give up */
352 /* make space for the key */
353 key->key = apr_palloc(p, key->keyLen);
357 apr_crypto_clear(p, key->key, key->keyLen);
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.
378 static 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)
382 apr_crypto_key_t *key = *k;
385 *k = key = apr_pcalloc(p, sizeof *key);
392 key->provider = f->provider;
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) {
400 switch (rec->ktype) {
402 case APR_CRYPTO_KTYPE_PASSPHRASE: {
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) {
416 case APR_CRYPTO_KTYPE_SECRET: {
418 /* sanity check - key correct size? */
419 if (rec->k.secret.secretLen != key->keyLen) {
420 return APR_EKEYLENGTH;
424 memcpy(key->key, rec->k.secret.secret, rec->k.secret.secretLen);
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
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.
467 static 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)
474 apr_crypto_key_t *key = *k;
477 *k = key = apr_pcalloc(p, sizeof *key);
484 key->provider = f->provider;
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) {
492 /* generate the key */
493 if ((f->result->rc = CCKeyDerivationPBKDF(kCCPBKDF2, pass, passLen, salt,
494 saltLen, kCCPRFHmacAlgSHA1, iterations, key->key, key->keyLen))
500 *ivSize = key->ivSize;
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
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.
522 static 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)
526 unsigned char *usedIv;
527 apr_crypto_block_t *block = *ctx;
529 *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
536 block->provider = key->provider;
539 apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
540 apr_pool_cleanup_null);
542 /* generate an IV, if necessary */
550 usedIv = apr_pcalloc(p, key->ivSize);
554 apr_crypto_clear(p, usedIv, key->ivSize);
555 status = apr_random_secure_bytes(block->f->rng, usedIv,
557 if (APR_SUCCESS != status) {
563 usedIv = (unsigned char *) *iv;
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))) {
573 case kCCParamError: {
576 case kCCMemoryFailure: {
579 case kCCAlignmentError: {
582 case kCCUnimplemented: {
591 *blockSize = key->blockSize;
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,
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
616 static 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)
620 apr_size_t outl = *outlen;
621 unsigned char *buffer;
623 /* are we after the maximum size of the out buffer? */
625 *outlen = CCCryptorGetOutputLength(ctx->ref, inlen, 1);
629 /* must we allocate the output buffer from a pool? */
631 outl = CCCryptorGetOutputLength(ctx->ref, inlen, 1);
632 buffer = apr_palloc(ctx->pool, outl);
636 apr_crypto_clear(ctx->pool, buffer, outl);
640 switch ((ctx->f->result->rc = CCCryptorUpdate(ctx->ref, in, inlen, (*out),
645 case kCCBufferTooSmall: {
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
674 * @return APR_ENOTIMPL if not implemented.
676 static apr_status_t crypto_block_encrypt_finish(unsigned char *out,
677 apr_size_t *outlen, apr_crypto_block_t *ctx)
679 apr_size_t len = *outlen;
681 ctx->f->result->rc = CCCryptorFinal(ctx->ref, out,
682 CCCryptorGetOutputLength(ctx->ref, 0, 1), &len);
684 /* always clean up */
685 crypto_block_cleanup(ctx);
687 switch (ctx->f->result->rc) {
691 case kCCBufferTooSmall: {
694 case kCCAlignmentError: {
697 case kCCDecodeError: {
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.
725 static 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)
729 apr_crypto_block_t *block = *ctx;
731 *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
738 block->provider = key->provider;
740 apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
741 apr_pool_cleanup_null);
743 /* generate an IV, if necessary */
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))) {
756 case kCCParamError: {
759 case kCCMemoryFailure: {
762 case kCCAlignmentError: {
765 case kCCUnimplemented: {
774 *blockSize = key->blockSize;
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,
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
799 static 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)
803 apr_size_t outl = *outlen;
804 unsigned char *buffer;
806 /* are we after the maximum size of the out buffer? */
808 *outlen = CCCryptorGetOutputLength(ctx->ref, inlen, 1);
812 /* must we allocate the output buffer from a pool? */
814 outl = CCCryptorGetOutputLength(ctx->ref, inlen, 1);
815 buffer = apr_palloc(ctx->pool, outl);
819 apr_crypto_clear(ctx->pool, buffer, outl);
823 switch ((ctx->f->result->rc = CCCryptorUpdate(ctx->ref, in, inlen, (*out),
828 case kCCBufferTooSmall: {
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
857 * @return APR_ENOTIMPL if not implemented.
859 static apr_status_t crypto_block_decrypt_finish(unsigned char *out,
860 apr_size_t *outlen, apr_crypto_block_t *ctx)
862 apr_size_t len = *outlen;
864 ctx->f->result->rc = CCCryptorFinal(ctx->ref, out,
865 CCCryptorGetOutputLength(ctx->ref, 0, 1), &len);
867 /* always clean up */
868 crypto_block_cleanup(ctx);
870 switch (ctx->f->result->rc) {
874 case kCCBufferTooSmall: {
877 case kCCAlignmentError: {
880 case kCCDecodeError: {
894 * OSX Common Crypto module.
896 APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_commoncrypto_driver =
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