static apr_status_t crypto_key()

in crypto/apr_crypto_commoncrypto.c [473:615]


static apr_status_t crypto_key(apr_crypto_key_t **k,
        const apr_crypto_key_rec_t *rec, const apr_crypto_t *f, apr_pool_t *p)
{
    apr_status_t rv;
    apr_crypto_key_t *key = *k;

    if (!key) {
        *k = key = apr_pcalloc(p, sizeof *key);
    }
    if (!key) {
        return APR_ENOMEM;
    }

    key->pool = p;
    key->f = f;
    key->provider = f->provider;
    key->rec = rec;

    switch (rec->ktype) {

    case APR_CRYPTO_KTYPE_PASSPHRASE: {

        /* decide on what cipher mechanism we will be using */
        rv = crypto_cipher_mechanism(key, rec->type, rec->mode, rec->pad, p);
        if (APR_SUCCESS != rv) {
            return rv;
        }

        /* generate the key */
        if ((f->result->rc = CCKeyDerivationPBKDF(kCCPBKDF2,
                rec->k.passphrase.pass, rec->k.passphrase.passLen,
                rec->k.passphrase.salt, rec->k.passphrase.saltLen,
                kCCPRFHmacAlgSHA1, rec->k.passphrase.iterations, key->key,
                key->keyLen)) == kCCParamError) {
            return APR_ENOKEY;
        }

        break;
    }

    case APR_CRYPTO_KTYPE_SECRET: {

        /* decide on what cipher mechanism we will be using */
        rv = crypto_cipher_mechanism(key, rec->type, rec->mode, rec->pad, p);
        if (APR_SUCCESS != rv) {
            return rv;
        }

        /* sanity check - key correct size? */
        if (rec->k.secret.secretLen != key->keyLen) {
            return APR_EKEYLENGTH;
        }

        /* copy the key */
        memcpy(key->key, rec->k.secret.secret, rec->k.secret.secretLen);

        break;
    }

    case APR_CRYPTO_KTYPE_HASH: {

        /* decide on what digest mechanism we will be using */
        rv = crypto_digest_mechanism(key, rec->k.hash.digest, p);
        if (APR_SUCCESS != rv) {
            return rv;
        }

        switch (rec->k.hash.digest) {
        case APR_CRYPTO_DIGEST_MD5:
            key->digestSize = CC_MD5_DIGEST_LENGTH;
            break;
        case APR_CRYPTO_DIGEST_SHA1:
            key->digestSize = CC_SHA1_DIGEST_LENGTH;
            break;
        case APR_CRYPTO_DIGEST_SHA224:
            key->digestSize = CC_SHA224_DIGEST_LENGTH;
            break;
        case APR_CRYPTO_DIGEST_SHA256:
            key->digestSize = CC_SHA256_DIGEST_LENGTH;
            break;
        case APR_CRYPTO_DIGEST_SHA384:
            key->digestSize = CC_SHA384_DIGEST_LENGTH;
            break;
        case APR_CRYPTO_DIGEST_SHA512:
            key->digestSize = CC_SHA512_DIGEST_LENGTH;
            break;
        default:
            return APR_ENODIGEST;
        }

        break;
    }
    case APR_CRYPTO_KTYPE_HMAC: {

        /* decide on what digest mechanism we will be using */
        rv = crypto_digest_mechanism(key, rec->k.hmac.digest, p);
        if (APR_SUCCESS != rv) {
            return rv;
        }

        key->hmac = rec->k.hmac.digest;

        switch (rec->k.hmac.digest) {
        case APR_CRYPTO_DIGEST_MD5:
            key->hmac = kCCHmacAlgMD5;
            break;
        case APR_CRYPTO_DIGEST_SHA1:
            key->hmac = kCCHmacAlgSHA1;
            break;
        case APR_CRYPTO_DIGEST_SHA224:
            key->hmac = kCCHmacAlgSHA224;
            break;
        case APR_CRYPTO_DIGEST_SHA256:
            key->hmac = kCCHmacAlgSHA256;
            break;
        case APR_CRYPTO_DIGEST_SHA384:
            key->hmac = kCCHmacAlgSHA384;
            break;
        case APR_CRYPTO_DIGEST_SHA512:
            key->hmac = kCCHmacAlgSHA512;
            break;
        default:
            return APR_ENODIGEST;
        }

        break;
    }

    case APR_CRYPTO_KTYPE_CMAC: {

        return APR_ENOTIMPL;

    }

    default: {

        return APR_ENOKEY;

    }
    }

    return APR_SUCCESS;
}