in crypto/apr_crypto_commoncrypto.c [714:801]
static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx,
const unsigned char **iv, const apr_crypto_key_t *key,
apr_size_t *blockSize, apr_pool_t *p)
{
unsigned char *usedIv;
apr_crypto_block_t *block = *ctx;
if (!block) {
*ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
}
if (!block) {
return APR_ENOMEM;
}
block->f = key->f;
block->pool = p;
block->provider = key->provider;
block->key = key;
apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
apr_pool_cleanup_null);
switch (key->rec->ktype) {
case APR_CRYPTO_KTYPE_PASSPHRASE:
case APR_CRYPTO_KTYPE_SECRET: {
/* generate an IV, if necessary */
usedIv = NULL;
if (key->ivSize) {
if (iv == NULL) {
return APR_ENOIV;
}
if (*iv == NULL) {
apr_status_t status;
usedIv = apr_pcalloc(p, key->ivSize);
if (!usedIv) {
return APR_ENOMEM;
}
apr_crypto_clear(p, usedIv, key->ivSize);
status = apr_random_secure_bytes(block->f->rng, usedIv,
key->ivSize);
if (APR_SUCCESS != status) {
return status;
}
*iv = usedIv;
} else {
usedIv = (unsigned char *) *iv;
}
}
/* create a new context for encryption */
switch ((block->f->result->rc = CCCryptorCreate(kCCEncrypt,
key->algorithm, key->options, key->key, key->keyLen, usedIv,
&block->ref))) {
case kCCSuccess: {
break;
}
case kCCParamError: {
return APR_EINIT;
}
case kCCMemoryFailure: {
return APR_ENOMEM;
}
case kCCAlignmentError: {
return APR_EPADDING;
}
case kCCUnimplemented: {
return APR_ENOTIMPL;
}
default: {
return APR_EINIT;
}
}
if (blockSize) {
*blockSize = key->blockSize;
}
return APR_SUCCESS;
}
default: {
return APR_EINVAL;
}
}
}