static apr_status_t crypto_block_encrypt_init()

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;

    }
    }

}