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;
}