static int test_oneshot(const struct ccdigest_info *di, test_vector *vector) {
    uint8_t answer[vector->result_len];
    byteBuffer salt = hexStringToBytes(vector->saltStr);
    ccpbkdf2_hmac(di, strlen(vector->password), vector->password, salt->len, salt->bytes, vector->iterations, vector->result_len, answer);
    ok(test_answer(di, vector, vector->result_len, answer), "check answer");
    free(salt);
    return 1;
}
static int test_size(const struct ccdigest_info *di) {
    size_t size_chk = 40;
    uint8_t output_buf[size_chk];
    static char *password = "******";
    static const uint8_t salt[16] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    };
    
    if(sizeof(size_t) > 4) { // only valid for 64 bit.
        size_t hlen = di->output_size;
        size_t too_big = hlen * ((size_t) UINT32_MAX + 1);
        ok(ccpbkdf2_hmac(di, strlen(password), password, sizeof(salt), salt, 10, too_big, output_buf) != 0, "Fails with size too big");
        ok(ccpbkdf2_hmac(di, strlen(password), password, sizeof(salt), salt, 10, size_chk, output_buf) == 0, "Passes");
    }
    return 1;
    
}
int 
CCKeyDerivationPBKDF( CCPBKDFAlgorithm algorithm, const char *password, size_t passwordLen,
					 const uint8_t *salt, size_t saltLen,
					 CCPseudoRandomAlgorithm prf, uint rounds, 
					 uint8_t *derivedKey, size_t derivedKeyLen)
{
    const struct ccdigest_info *di;

    CC_DEBUG_LOG(ASL_LEVEL_ERR, "PasswordLen %lu SaltLen %lU PRF %d Rounds %u DKLen %lu\n", passwordLen, saltLen, prf, rounds, derivedKeyLen);
    if(algorithm != kCCPBKDF2) return -1;
    switch(prf) {
        case kCCPRFHmacAlgSHA1: di = CCDigestGetDigestInfo(kCCDigestSHA1); break;
        case kCCPRFHmacAlgSHA224: di = CCDigestGetDigestInfo(kCCDigestSHA224); break;
        case kCCPRFHmacAlgSHA256: di = CCDigestGetDigestInfo(kCCDigestSHA256); break;
        case kCCPRFHmacAlgSHA384: di = CCDigestGetDigestInfo(kCCDigestSHA384); break;
        case kCCPRFHmacAlgSHA512: di = CCDigestGetDigestInfo(kCCDigestSHA512); break;
        default: return -1;
    }
    if(!password || !salt || !derivedKey || (derivedKeyLen == 0) || (rounds == 0)) return -1;
    
    ccpbkdf2_hmac(di, passwordLen, password, saltLen, salt, rounds, derivedKeyLen, derivedKey);
    return 0;
}