static void crypt_all(int count) { int index = 0; #ifdef _OPENMP #pragma omp parallel for for (index = 0; index < count; index++) #endif { unsigned char master[32]; unsigned char output[1024]; unsigned char *iv_in; unsigned char iv_out[16]; int size; int page_sz = 1008; /* 1024 - strlen(SQLITE_FILE_HEADER) */ int reserve_sz = 16; /* for HMAC off case */ AES_KEY akey; pbkdf2((unsigned char *)saved_key[index], strlen(saved_key[index]), cur_salt->salt, 16, ITERATIONS, (uint32_t *)master); memcpy(output, SQLITE_FILE_HEADER, FILE_HEADER_SZ); size = page_sz - reserve_sz; iv_in = cur_salt->data + size + 16; memcpy(iv_out, iv_in, 16); if (AES_set_decrypt_key(master, 256, &akey) < 0) { fprintf(stderr, "AES_set_derypt_key failed!\n"); } /* decrypting 24 bytes is enough */ AES_cbc_encrypt(cur_salt->data + 16, output + 16, 24, &akey, iv_out, AES_DECRYPT); if (verify_page(output) == 0) { cracked[index] = 1; } else cracked[index] = 0; } }
u8 GetHiddenVolumeSlotKey (u8 * HiddenVolumeKey_pu8, u8 * Password_pu8, u32 PasswordLen_u32, u8 * Salt_pu8, u32 SaltLen_u32) { u8 output_au8[64]; #ifdef LOCAL_DEBUG CI_LocalPrintf ("Password_pu8 : Len %2d -%s-\r\n", PasswordLen_u32, Password_pu8); CI_LocalPrintf ("Salt : "); HexPrint (SaltLen_u32, Salt_pu8); CI_LocalPrintf ("\r\n"); #endif #ifndef SAVE_FLASH_MEMORY_NO_PBKDF2 pbkdf2 (output_au8, Password_pu8, PasswordLen_u32, Salt_pu8, SaltLen_u32); memcpy (HiddenVolumeKey_pu8, output_au8, AES_KEYSIZE_256_BIT); // copy 256 bit from the 512 bit output #else CI_LocalPrintf ("*** WARNING low security for hidden volumes ***\r\n"); // use the base key as the key #endif #ifdef LOCAL_DEBUG CI_LocalPrintf ("Key : "); HexPrint (32, HiddenVolumeKey_pu8); CI_LocalPrintf ("\r\n"); #endif return (TRUE); }
void TestPBKDF2() // Test PBKDF2 HMAC-SHA256 { byte Key[32],V1[32],V2[32]; pbkdf2((byte *)"password", 8, (byte *)"salt", 4, Key, V1, V2, 1); byte Res1[32]={0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, 0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, 0xa8, 0x65, 0x48, 0xc9, 0x2c, 0xcc, 0x35, 0x48, 0x08, 0x05, 0x98, 0x7c, 0xb7, 0x0b, 0xe1, 0x7b }; mprintf(L"\nPBKDF2 test1: %s", memcmp(Key,Res1,32)==0 ? L"OK":L"Failed"); pbkdf2((byte *)"password", 8, (byte *)"salt", 4, Key, V1, V2, 4096); byte Res2[32]={0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, 0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, 0x96, 0x28, 0x93, 0xa0, 0x01, 0xce, 0x4e, 0x11, 0xa4, 0x96, 0x38, 0x73, 0xaa, 0x98, 0x13, 0x4a }; mprintf(L"\nPBKDF2 test2: %s", memcmp(Key,Res2,32)==0 ? L"OK":L"Failed"); pbkdf2((byte *)"just some long string pretending to be a password", 49, (byte *)"salt, salt, salt, a lot of salt", 31, Key, V1, V2, 65536); byte Res3[32]={0x08, 0x0f, 0xa3, 0x1d, 0x42, 0x2d, 0xb0, 0x47, 0x83, 0x9b, 0xce, 0x3a, 0x3b, 0xce, 0x49, 0x51, 0xe2, 0x62, 0xb9, 0xff, 0x76, 0x2f, 0x57, 0xe9, 0xc4, 0x71, 0x96, 0xce, 0x4b, 0x6b, 0x6e, 0xbf}; mprintf(L"\nPBKDF2 test3: %s", memcmp(Key,Res3,32)==0 ? L"OK":L"Failed"); }
// Non-public secure PBKDF2 hash function with salting and 1,337 iterations std::string JSI_Lobby::EncryptPassword(const std::string& password, const std::string& username) { const int DIGESTSIZE = SHA_DIGEST_SIZE; const int ITERATIONS = 1337; static const unsigned char salt_base[DIGESTSIZE] = { 244, 243, 249, 244, 32, 33, 34, 35, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 32, 33, 244, 224, 127, 129, 130, 140, 153, 133, 123, 234, 123 }; // initialize the salt buffer unsigned char salt_buffer[DIGESTSIZE] = {0}; SHA256 hash; hash.update(salt_base, sizeof(salt_base)); hash.update(username.c_str(), username.length()); hash.finish(salt_buffer); // PBKDF2 to create the buffer unsigned char encrypted[DIGESTSIZE]; pbkdf2(encrypted, (unsigned char*)password.c_str(), password.length(), salt_buffer, DIGESTSIZE, ITERATIONS); static const char base16[] = "0123456789ABCDEF"; char hex[2 * DIGESTSIZE]; for (int i = 0; i < DIGESTSIZE; ++i) { hex[i*2] = base16[encrypted[i] >> 4]; // 4 high bits hex[i*2 + 1] = base16[encrypted[i] & 0x0F]; // 4 low bits } return std::string(hex, sizeof(hex)); }
krb5_error_code krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash, const krb5_data *out, unsigned long count, const krb5_data *pass, const krb5_data *salt) { krb5_keyblock keyblock; char tmp[128]; krb5_data d; krb5_crypto_iov iov; krb5_error_code err; assert(hash->hashsize <= sizeof(tmp)); if (pass->length > hash->blocksize) { d = make_data(tmp, hash->hashsize); iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *pass; err = hash->hash(&iov, 1, &d); if (err) return err; keyblock.length = d.length; keyblock.contents = (krb5_octet *) d.data; } else { keyblock.length = pass->length; keyblock.contents = (krb5_octet *) pass->data; } keyblock.enctype = ENCTYPE_NULL; err = pbkdf2(hash, &keyblock, salt, count, out); return err; }
std::string hashForUser(const std::string& username) { std::string password; if (username == "user") { password = "******"; } else if (username == "admin") { password = "******"; } else return ""; Poco::MD5Engine md5; md5.update(username); md5.update(std::string(":poco:")); md5.update(password); std::string hashedPassword = digestToHexString(md5); int iterations; std::string salt = saltForUser(username, iterations); Poco::PBKDF2Engine<Poco::HMACEngine<Poco::SHA1Engine> > pbkdf2(salt, iterations, 20); pbkdf2.update(hashedPassword); return digestToBinaryString(pbkdf2); }
OctetString pbkdf2_hmac_hash(const std::string& password, const SecureVector& salt, int desiredKeyLength, int iterations) { T hashObject; Botan::HMAC hmac(&hashObject); Botan::PKCS5_PBKDF2 pbkdf2(&hmac); return pbkdf2.derive_key(desiredKeyLength, password, salt.data(), salt.size(), iterations); }
void CryptData::SetKey50(bool Encrypt,SecPassword *Password,const wchar *PwdW, const byte *Salt,const byte *InitV,uint Lg2Cnt,byte *HashKey, byte *PswCheck) { if (Lg2Cnt>CRYPT5_KDF_LG2_COUNT_MAX) return; byte Key[32],PswCheckValue[SHA256_DIGEST_SIZE],HashKeyValue[SHA256_DIGEST_SIZE]; bool Found=false; for (uint I=0;I<ASIZE(KDF5Cache);I++) { KDF5CacheItem *Item=KDF5Cache+I; if (Item->Lg2Count==Lg2Cnt && Item->Pwd==*Password && memcmp(Item->Salt,Salt,SIZE_SALT50)==0) { SecHideData(Item->Key,sizeof(Item->Key),false,false); memcpy(Key,Item->Key,sizeof(Key)); SecHideData(Item->Key,sizeof(Item->Key),true,false); memcpy(PswCheckValue,Item->PswCheckValue,sizeof(PswCheckValue)); memcpy(HashKeyValue,Item->HashKeyValue,sizeof(HashKeyValue)); Found=true; break; } } if (!Found) { char PwdUtf[MAXPASSWORD*4]; WideToUtf(PwdW,PwdUtf,ASIZE(PwdUtf)); pbkdf2((byte *)PwdUtf,strlen(PwdUtf),Salt,SIZE_SALT50,Key,HashKeyValue,PswCheckValue,(1<<Lg2Cnt)); cleandata(PwdUtf,sizeof(PwdUtf)); KDF5CacheItem *Item=KDF5Cache+(KDF5CachePos++ % ASIZE(KDF5Cache)); Item->Lg2Count=Lg2Cnt; Item->Pwd=*Password; memcpy(Item->Salt,Salt,SIZE_SALT50); memcpy(Item->Key,Key,sizeof(Key)); memcpy(Item->PswCheckValue,PswCheckValue,sizeof(PswCheckValue)); memcpy(Item->HashKeyValue,HashKeyValue,sizeof(HashKeyValue)); SecHideData(Item->Key,sizeof(Key),true,false); } if (HashKey!=NULL) memcpy(HashKey,HashKeyValue,SHA256_DIGEST_SIZE); if (PswCheck!=NULL) { memset(PswCheck,0,SIZE_PSWCHECK); for (uint I=0;I<SHA256_DIGEST_SIZE;I++) PswCheck[I%SIZE_PSWCHECK]^=PswCheckValue[I]; cleandata(PswCheckValue,sizeof(PswCheckValue)); } // NULL initialization vector is possible if we only need the password // check value for archive encryption header. if (InitV!=NULL) rin.Init(Encrypt, Key, 256, InitV); cleandata(Key,sizeof(Key)); }
int try_decrypt(char *passphrase) { struct xts_ctx *xts_ctx; struct pbkdf_prf *prf; int dklen = 64; uint8_t *dk; uint32_t sector = 0; uint32_t crc; int ret = -1; dk = malloc(dklen); xts_ctx = malloc(sizeof(struct xts_ctx)); for (prf = &prfs[0]; prf->hmac_fn != NULL; ++prf) { /* We decrypt in place, so we have to re-read every time */ bios_read_sectors(biosdev, &hdr, 63, 1); pbkdf2(dk, dklen, passphrase, strlen(passphrase), hdr.enc.salt, SALT_LEN, prf->iterations, prf->hmac_fn, prf->digest_sz); #ifdef DEBUG bios_print_hex(dk, dklen); bios_print("\r\n"); #endif xts_init(xts_ctx, aes256_init, aes256_encrypt_ecb, aes256_decrypt_ecb, 16, dk, dklen); xts_decrypt(xts_ctx, hdr.enc.enc, sizeof(hdr.enc.enc), §or, sizeof(sector)); xts_uninit(xts_ctx); if (memcmp(hdr.dec.tc_str, TC_SIG, sizeof(hdr.dec.tc_str)) != 0) { bios_print("Signature mismatch\r\n"); continue; } bswap_inplace(&hdr.dec.tc_ver, sizeof(hdr.dec.tc_ver)); bswap_inplace(&hdr.dec.crc_keys, sizeof(hdr.dec.crc_keys)); bswap_inplace(&hdr.dec.off_mk_scope, sizeof(hdr.dec.off_mk_scope)); bswap_inplace(&hdr.dec.sz_mk_scope, sizeof(hdr.dec.sz_mk_scope)); bswap_inplace(&hdr.dec.flags, sizeof(hdr.dec.flags)); crc = crc32((void *)hdr.dec.keys, sizeof(hdr.dec.keys)); if (crc != hdr.dec.crc_keys) { bios_print("Keys CRC mismatch\r\n"); continue; } ret = 0; break; } free (dk, dklen); free (xts_ctx, sizeof(struct xts_ctx)); return ret; }
void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed[512 / 8], void (*progress_callback)(uint32_t current, uint32_t total)) { static uint8_t salt[8 + 256 + 4]; int saltlen = strlen(passphrase); memcpy(salt, "mnemonic", 8); memcpy(salt + 8, passphrase, saltlen); saltlen += 8; pbkdf2((const uint8_t *)mnemonic, strlen(mnemonic), salt, saltlen, PBKDF2_ROUNDS, seed, 512 / 8, progress_callback); }
static int derive_key(libzfs_handle_t *hdl, zfs_keyformat_t format, uint64_t iters, uint8_t *key_material, size_t key_material_len, uint64_t salt, uint8_t **key_out) { int ret; uint8_t *key; *key_out = NULL; key = zfs_alloc(hdl, WRAPPING_KEY_LEN); if (!key) return (ENOMEM); switch (format) { case ZFS_KEYFORMAT_RAW: bcopy(key_material, key, WRAPPING_KEY_LEN); break; case ZFS_KEYFORMAT_HEX: ret = hex_key_to_raw((char *)key_material, WRAPPING_KEY_LEN * 2, key); if (ret != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Invalid hex key provided.")); goto error; } break; case ZFS_KEYFORMAT_PASSPHRASE: salt = LE_64(salt); ret = pbkdf2(key_material, strlen((char *)key_material), ((uint8_t *)&salt), sizeof (uint64_t), iters, key, WRAPPING_KEY_LEN); if (ret != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Failed to generate key from passphrase.")); goto error; } break; default: ret = EINVAL; goto error; } *key_out = key; return (0); error: free(key); *key_out = NULL; return (ret); }
static void pbkdf2_hmac_sha1_deriviation(const uint8_t *passphrase, size_t passphrase_length, const uint8_t *salt, size_t salt_length, size_t iterations, uint8_t *key_out, size_t key_length) { // MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20; uint8_t temp_data[3*20+salt_length]; pbkdf2(hmac_sha1, 20, passphrase, passphrase_length, salt, salt_length, iterations, key_out, key_length, temp_data); }
END_TEST // test vectors from http://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors START_TEST(test_pbkdf2) { uint8_t k[64], s[64]; strcpy((char *)s, "salt"); pbkdf2((uint8_t *)"password", 8, s, 4, 1, k, 64, 0); ck_assert_mem_eq(k, fromhex("867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce"), 64); strcpy((char *)s, "salt"); pbkdf2((uint8_t *)"password", 8, s, 4, 2, k, 64, 0); ck_assert_mem_eq(k, fromhex("e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e"), 64); strcpy((char *)s, "salt"); pbkdf2((uint8_t *)"password", 8, s, 4, 4096, k, 64, 0); ck_assert_mem_eq(k, fromhex("d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5"), 64); strcpy((char *)s, "saltSALTsaltSALTsaltSALTsaltSALTsalt"); pbkdf2((uint8_t *)"passwordPASSWORDpassword", 3*8, s, 9*4, 4096, k, 64, 0); ck_assert_mem_eq(k, fromhex("8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8"), 64); }
static vector<u8> H5(const vector<u8>& ps, const vector<u8>& s, const vector<u8>& rc, const vector<u8>& rs) { vector<u8> pass = ps; pass.insert(pass.end(), s.begin(), s.end()); pass.insert(pass.end(), rs.begin(), rs.end()); pass.insert(pass.end(), rc.begin(), rc.end()); return pbkdf2(hmac_whirlpool, pass, vector<u8>(kSalt5.begin(), kSalt5.end()), kH5Iters, kAESKeyLen); }
int _pbkdf2_vrfy(const unsigned char *pass, unsigned long pass_len, const unsigned char *salt, unsigned long salt_len, int iter, int hash_idx, const unsigned char *vrfy, unsigned long *vrfylen) { unsigned char *out = safe_malloc(*vrfylen); int err; if ((err = pbkdf2(pass, pass_len, salt, salt_len, iter, hash_idx, out, vrfylen)) != CRYPT_OK) { safe_free(out); return err; } if (memcmp(vrfy, out, *vrfylen) != 0) { safe_free(out); return CRYPT_ERROR; } safe_free(out); return CRYPT_OK; }
int main(int argc, char* argv[]) { size_t i; unsigned char out[32]; if (argc < 2 || argc > 3) { printf("Error. Usage: ./stetch hash [iterations]"); return 1; } long iterations = 5000000000; if (argc == 3) iterations = strtol(argv[2], NULL, 10); pbkdf2(argv[1], "pevpot", iterations, EVP_sha256(), out); for(i=0;i<32;i++) { printf("%02x", out[i]); } printf("\n"); }
/* This implements the HMAC SHA-1 version of pbkdf2 and allocates a local buffer for the HMAC */ void pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen, const uint8_t *saltPtr, size_t saltLen, uint32_t iterationCount, void *dkPtr, size_t dkLen) { // MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20; // salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize. const size_t kBigEnoughSize = (saltLen + CC_SHA1_DIGEST_LENGTH) + 2 * CC_SHA1_DIGEST_LENGTH; uint8_t temp_data[kBigEnoughSize]; pbkdf2(hmac_sha1_PRF, CC_SHA1_DIGEST_LENGTH, passwordPtr, passwordLen, saltPtr, saltLen, iterationCount, dkPtr, dkLen, temp_data); bzero(temp_data, kBigEnoughSize); }
void pbkdf2(void) { PBKDF2 pbkdf2(QString("message").toUtf8(), QString("pepper").toUtf8(), 3, QCryptographicHash::Sha512); QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("2646f9ccb58d21406815bafc62245771bf80aaa080a633ff1bdd660eb44f369a89da48fb041c5551a118de20cfb8b96b92e7a9945425ba889e9ad645614522eb")); }
struct tchdr_enc *copy_reencrypt_hdr(unsigned char *pass, int passlen, struct pbkdf_prf_algo *prf_algo, int weak, struct tcplay_info *info, struct tchdr_enc **backup_hdr) { struct tchdr_enc *ehdr, *ehdr_backup; unsigned char *key, *key_backup; unsigned char iv[128]; int error; key = key_backup = NULL; ehdr = ehdr_backup = NULL; /* By default stick to current PRF algo */ if (prf_algo == NULL) prf_algo = info->pbkdf_prf; if ((ehdr = (struct tchdr_enc *)alloc_safe_mem(sizeof(*ehdr))) == NULL) { tc_log(1, "could not allocate safe ehdr memory\n"); goto error; } if ((ehdr_backup = (struct tchdr_enc *)alloc_safe_mem (sizeof(*ehdr_backup))) == NULL) { tc_log(1, "could not allocate safe ehdr_backup memory\n"); goto error; } if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) { tc_log(1, "could not allocate safe key memory\n"); goto error; } if ((key_backup = alloc_safe_mem(MAX_KEYSZ)) == NULL) { tc_log(1, "could not allocate safe backup key memory\n"); goto error; } if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) { tc_log(1, "could not get salt\n"); goto error; } if ((error = get_random(ehdr_backup->salt, sizeof(ehdr_backup->salt), weak)) != 0) { tc_log(1, "could not get salt for backup header\n"); goto error; } error = pbkdf2(prf_algo, (char *)pass, passlen, ehdr->salt, sizeof(ehdr->salt), MAX_KEYSZ, key); if (error) { tc_log(1, "could not derive key\n"); goto error; } error = pbkdf2(prf_algo, (char *)pass, passlen, ehdr_backup->salt, sizeof(ehdr_backup->salt), MAX_KEYSZ, key_backup); if (error) { tc_log(1, "could not derive backup key\n"); goto error; } HOST_TO_BE(16, info->hdr->tc_ver); HOST_TO_BE(16, info->hdr->tc_min_ver); HOST_TO_BE(32, info->hdr->crc_keys); HOST_TO_BE(64, info->hdr->vol_ctime); HOST_TO_BE(64, info->hdr->hdr_ctime); HOST_TO_BE(64, info->hdr->sz_vol); HOST_TO_BE(64, info->hdr->sz_hidvol); HOST_TO_BE(64, info->hdr->off_mk_scope); HOST_TO_BE(64, info->hdr->sz_mk_scope); HOST_TO_BE(32, info->hdr->sec_sz); HOST_TO_BE(32, info->hdr->flags); HOST_TO_BE(32, info->hdr->crc_dhdr); memset(iv, 0, sizeof(iv)); error = tc_encrypt(info->cipher_chain, key, iv, (unsigned char *)info->hdr, sizeof(struct tchdr_dec), ehdr->enc); if (error) { tc_log(1, "Header encryption failed\n"); goto error; } memset(iv, 0, sizeof(iv)); error = tc_encrypt(info->cipher_chain, key_backup, iv, (unsigned char *)info->hdr, sizeof(struct tchdr_dec), ehdr_backup->enc); if (error) { tc_log(1, "Backup header encryption failed\n"); goto error; } free_safe_mem(key); free_safe_mem(key_backup); if (backup_hdr != NULL) *backup_hdr = ehdr_backup; else free_safe_mem(ehdr_backup); return ehdr; /* NOT REACHED */ error: if (key) free_safe_mem(key); if (key_backup) free_safe_mem(key_backup); if (ehdr) free_safe_mem(ehdr); if (ehdr_backup) free_safe_mem(ehdr_backup); return NULL; }
struct tchdr_enc * create_hdr(unsigned char *pass, int passlen, struct pbkdf_prf_algo *prf_algo, struct tc_cipher_chain *cipher_chain, size_t sec_sz, disksz_t total_blocks __unused, off_t offset, disksz_t blocks, int veracrypt_mode, int hidden, int weak, struct tchdr_enc **backup_hdr) { struct tchdr_enc *ehdr, *ehdr_backup; struct tchdr_dec *dhdr; unsigned char *key, *key_backup; unsigned char iv[128]; int error; key = key_backup = NULL; dhdr = NULL; ehdr = ehdr_backup = NULL; if (backup_hdr != NULL) *backup_hdr = NULL; if ((dhdr = (struct tchdr_dec *)alloc_safe_mem(sizeof(*dhdr))) == NULL) { tc_log(1, "could not allocate safe dhdr memory\n"); goto error; } if ((ehdr = (struct tchdr_enc *)alloc_safe_mem(sizeof(*ehdr))) == NULL) { tc_log(1, "could not allocate safe ehdr memory\n"); goto error; } if ((ehdr_backup = (struct tchdr_enc *)alloc_safe_mem (sizeof(*ehdr_backup))) == NULL) { tc_log(1, "could not allocate safe ehdr_backup memory\n"); goto error; } if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) { tc_log(1, "could not allocate safe key memory\n"); goto error; } if ((key_backup = alloc_safe_mem(MAX_KEYSZ)) == NULL) { tc_log(1, "could not allocate safe backup key memory\n"); goto error; } if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) { tc_log(1, "could not get salt\n"); goto error; } if ((error = get_random(ehdr_backup->salt, sizeof(ehdr_backup->salt), weak)) != 0) { tc_log(1, "could not get salt for backup header\n"); goto error; } error = pbkdf2(prf_algo, (char *)pass, passlen, ehdr->salt, sizeof(ehdr->salt), MAX_KEYSZ, key); if (error) { tc_log(1, "could not derive key\n"); goto error; } error = pbkdf2(prf_algo, (char *)pass, passlen, ehdr_backup->salt, sizeof(ehdr_backup->salt), MAX_KEYSZ, key_backup); if (error) { tc_log(1, "could not derive backup key\n"); goto error; } memset(dhdr, 0, sizeof(*dhdr)); if ((error = get_random(dhdr->keys, sizeof(dhdr->keys), weak)) != 0) { tc_log(1, "could not get key random bits\n"); goto error; } if (veracrypt_mode == 0) { memcpy(dhdr->tc_str, TC_SIG, 4); dhdr->tc_ver = 5; dhdr->tc_min_ver = 0x0700; } else { memcpy(dhdr->tc_str, VC_SIG, 4); dhdr->tc_ver = 5; dhdr->tc_min_ver = 0x010b; } dhdr->crc_keys = crc32((void *)&dhdr->keys, 256); dhdr->sz_vol = blocks * sec_sz; if (hidden) dhdr->sz_hidvol = dhdr->sz_vol; dhdr->off_mk_scope = offset * sec_sz; dhdr->sz_mk_scope = blocks * sec_sz; dhdr->sec_sz = sec_sz; dhdr->flags = 0; HOST_TO_BE(16, dhdr->tc_ver); HOST_TO_BE(16, dhdr->tc_min_ver); HOST_TO_BE(32, dhdr->crc_keys); HOST_TO_BE(64, dhdr->sz_vol); HOST_TO_BE(64, dhdr->sz_hidvol); HOST_TO_BE(64, dhdr->off_mk_scope); HOST_TO_BE(64, dhdr->sz_mk_scope); HOST_TO_BE(32, dhdr->sec_sz); HOST_TO_BE(32, dhdr->flags); dhdr->crc_dhdr = crc32((void *)dhdr, 188); HOST_TO_BE(32, dhdr->crc_dhdr); memset(iv, 0, sizeof(iv)); error = tc_encrypt(cipher_chain, key, iv, (unsigned char *)dhdr, sizeof(struct tchdr_dec), ehdr->enc); if (error) { tc_log(1, "Header encryption failed\n"); goto error; } memset(iv, 0, sizeof(iv)); error = tc_encrypt(cipher_chain, key_backup, iv, (unsigned char *)dhdr, sizeof(struct tchdr_dec), ehdr_backup->enc); if (error) { tc_log(1, "Backup header encryption failed\n"); goto error; } free_safe_mem(key); free_safe_mem(key_backup); free_safe_mem(dhdr); if (backup_hdr != NULL) *backup_hdr = ehdr_backup; else free_safe_mem(ehdr_backup); return ehdr; /* NOT REACHED */ error: if (key) free_safe_mem(key); if (key_backup) free_safe_mem(key_backup); if (dhdr) free_safe_mem(dhdr); if (ehdr) free_safe_mem(ehdr); if (ehdr_backup) free_safe_mem(ehdr_backup); return NULL; }
bool BotanWrapper::EncryptFile(QString Source, QString Destination) { QFileInfo name = Source; QString base = name.baseName(); QString encrypted1 = eoutput + base + ".gg"; QString encrypted2 = toutput + base + ".twofish"; QFile e(encrypted1); QFile t(encrypted2); try { //Setup the key derive functions PKCS5_PBKDF2 pbkdf2(new HMAC(new Keccak_1600)); const u32bit PBKDF2_ITERATIONS = 700000; qDebug() << "create keys"; //Create the KEY and IV KDF* kdf = get_kdf("KDF2(SHA-512)"); AutoSeeded_RNG rng; qDebug() << "create salt"; SecureVector<byte> salt(256); rng.randomize(&salt[0], salt.size()); mSalt = salt; qDebug() << "create master key"; //Create the master key SecureVector<byte> mMaster = pbkdf2.derive_key(128, mPassword.toStdString(), &mSalt[0], mSalt.size(),PBKDF2_ITERATIONS).bits_of(); SymmetricKey mKey = kdf->derive_key(32, mMaster, "salt1"); InitializationVector mIV = kdf->derive_key(16, mMaster, "salt2"); qDebug() << "start encryption"; string inFilename = Source.toStdString(); string outFilename = encrypted1.toStdString(); std::ifstream inFile(inFilename.c_str()); std::ofstream outFile(outFilename.c_str()); Pipe pipe(get_cipher("AES-256/EAX", mKey, mIV,ENCRYPTION),new DataSink_Stream(outFile)); outFile.write((const char*)mSalt.begin(), mSalt.size()); pipe.start_msg(); inFile >> pipe; pipe.end_msg(); outFile.flush(); outFile.close(); inFile.close(); QMessageBox msgBox; /*****************TWOFISH ENCRYPTION********************/ qDebug() << "Twofish"; //Setup the key derive functions PKCS5_PBKDF2 pbkdf3(new HMAC(new Skein_512)); //Create the KEY and IV KDF* kdf2 = get_kdf("KDF2(Whirlpool)"); SecureVector<byte> salt2(256); rng.randomize(&salt2[0], salt2.size()); mSalt2 = salt2; //Create the master key SecureVector<byte> mMaster2 = pbkdf3.derive_key(128, mPassword2.toStdString(), &mSalt2[0], mSalt2.size(),PBKDF2_ITERATIONS).bits_of(); SymmetricKey mKey2 = kdf2->derive_key(32, mMaster2, "salt1"); InitializationVector mIV2 = kdf2->derive_key(16, mMaster2, "salt2"); string inFilename2 = encrypted1.toStdString(); string outFilename2 = encrypted2.toStdString(); std::ifstream inFile2(inFilename2.c_str()); std::ofstream outFile2(outFilename2.c_str()); Pipe pipe2(get_cipher("Twofish/CFB", mKey2, mIV2,ENCRYPTION),new DataSink_Stream(outFile2)); outFile2.write((const char*)mSalt2.begin(), mSalt2.size()); pipe2.start_msg(); inFile2 >> pipe2; pipe2.end_msg(); outFile2.flush(); outFile2.close(); inFile2.close(); /**************************SERPENT ENCRYPTION*****************/ //Create the KEY and IV KDF* kdf3 = get_kdf("KDF2(Tiger)"); SecureVector<byte> salt3(256); rng.randomize(&salt3[0], salt3.size()); mSalt3 = salt3; //Create the master key SecureVector<byte> mMaster3 = pbkdf2.derive_key(128, mPassword3.toStdString(), &mSalt3[0], mSalt3.size(),PBKDF2_ITERATIONS).bits_of(); SymmetricKey mKey3 = kdf3->derive_key(32, mMaster3, "salt1"); InitializationVector mIV3 = kdf3->derive_key(16, mMaster3, "salt2"); string inFilename3 = encrypted2.toStdString(); string outFilename3 = Destination.toStdString(); std::ifstream inFile3(inFilename3.c_str()); std::ofstream outFile3(outFilename3.c_str()); qDebug() << "serpent"; Pipe pipe3(get_cipher("Serpent/CBC/PKCS7", mKey3, mIV3,ENCRYPTION),new DataSink_Stream(outFile3)); outFile3.write((const char*)mSalt3.begin(), mSalt3.size()); pipe3.start_msg(); inFile3 >> pipe3; pipe3.end_msg(); outFile3.flush(); outFile3.close(); inFile3.close(); msgBox.setText("Success!"); msgBox.setInformativeText("File successfully encrypted!"); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); e.remove(); t.remove(); return true; } catch(...) { return false; } }
bool BotanWrapper::DecryptFile(QString Source, QString Destination) { //qDebug() << "\n\n"; QFileInfo name = Source; //qDebug() << Source; QString base = name.baseName(); //qDebug() << base; QString encrypted3 = soutput + base + ".serpentdecrypted"; //qDebug() << soutput; QString encrypted4 = tfoutput + base + ".twofishdecrypted"; //qDebug() << toutput; try { //Setup the key derive functions PKCS5_PBKDF2 pbkdf2(new HMAC(new Keccak_1600)); const u32bit PBKDF2_ITERATIONS = 700000; string inFilename3 = Source.toStdString(); string outFilename3 = encrypted3.toStdString(); std::ifstream in3(inFilename3.c_str(),std::ios::binary); std::ofstream out3(outFilename3.c_str(),std::ios::binary); char* salt3 = new char[256]; in3.read(salt3 , 256 ); qDebug() << "create salt"; SecureVector<byte> salts3((const byte*)salt3, 256 ) ; mSalt3 = salts3; //Create the KEY and IV KDF* kdf3 = get_kdf("KDF2(Tiger)"); qDebug() << "create master key"; //Create the master key SecureVector<byte> mMaster3 = pbkdf2.derive_key(128, mPassword3.toStdString(), &mSalt3[0], mSalt3.size(),PBKDF2_ITERATIONS).bits_of(); SymmetricKey mKey3 = kdf3->derive_key(32, mMaster3, "salt1"); InitializationVector mIV3 = kdf3->derive_key(16, mMaster3, "salt2"); qDebug() << "begin serpent decrypt"; Pipe pipe3(get_cipher("Serpent/CBC/PKCS7", mKey3, mIV3,DECRYPTION),new DataSink_Stream(out3)); pipe3.start_msg(); in3 >> pipe3; pipe3.end_msg(); out3.flush(); out3.close(); in3.close(); /*************************TWOFISH DECRYPTION*************************/ PKCS5_PBKDF2 pbkdf3(new HMAC(new Skein_512)); string inFilename2 = encrypted3.toStdString(); string outFilename2 = encrypted4.toStdString(); std::ifstream in2(inFilename2.c_str(),std::ios::binary); std::ofstream out2(outFilename2.c_str(),std::ios::binary); char* salt2 = new char[256]; in2.read(salt2 , 256 ); SecureVector<byte> salts2((const byte*)salt2, 256 ) ; mSalt2 = salts2; //Create the KEY and IV KDF* kdf2 = get_kdf("KDF2(Whirlpool)"); //Create the master key SecureVector<byte> mMaster2 = pbkdf3.derive_key(128, mPassword2.toStdString(), &mSalt2[0], mSalt2.size(),PBKDF2_ITERATIONS).bits_of(); SymmetricKey mKey2 = kdf2->derive_key(32, mMaster2, "salt1"); InitializationVector mIV2 = kdf2->derive_key(16, mMaster2, "salt2"); qDebug() << "twofish"; Pipe pipe2(get_cipher("Twofish/CFB", mKey2, mIV2,DECRYPTION),new DataSink_Stream(out2)); pipe2.start_msg(); in2 >> pipe2; pipe2.end_msg(); out2.flush(); out2.close(); in2.close(); /************AES DECRYPTION*************************/ string inFilename = encrypted4.toStdString(); string outFilename = Destination.toStdString(); std::ifstream in(inFilename.c_str(),std::ios::binary); std::ofstream out(outFilename.c_str(),std::ios::binary); char* salt = new char[256]; in.read(salt , 256 ); SecureVector<byte> salts((const byte*)salt, 256 ) ; mSalt = salts; //Create the KEY and IV KDF* kdf = get_kdf("KDF2(SHA-512)"); //Create the master key SecureVector<byte> mMaster = pbkdf2.derive_key(128, mPassword.toStdString(), &mSalt[0], mSalt.size(),PBKDF2_ITERATIONS).bits_of(); SymmetricKey mKey = kdf->derive_key(32, mMaster, "salt1"); InitializationVector mIV = kdf->derive_key(16, mMaster, "salt2"); qDebug() << "AES"; Pipe pipe(get_cipher("AES-256/EAX", mKey, mIV,DECRYPTION),new DataSink_Stream(out)); pipe.start_msg(); in >> pipe; pipe.end_msg(); out.flush(); out.close(); in.close(); QMessageBox msgBox; msgBox.setText("Success!"); msgBox.setInformativeText("File successfully decrypted!"); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); QFile s(encrypted3), t(encrypted4); s.remove(); t.remove(); return true; } catch(...) { return false; } }
void pbkdf2_empty_salt(void) { PBKDF2 pbkdf2(QString("message").toUtf8(), QByteArray(), 3, QCryptographicHash::Sha512); QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("b8ec13cfc9b9d49ca1143018ce8413a962c09c0063f30a466df802897475c57f268d91cc568ac1b6a9f19b1a0db10f30058fb7a453b2675010ef2b5f96487ad3")); }
void pbkdf2_empty_message(void) { PBKDF2 pbkdf2(SecureByteArray(), QString("pepper").toUtf8(), 3, QCryptographicHash::Sha512); QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("9dd331fc67421e1dce619cbbb517170e2dc325491d3426425630c4c01fd0eca8d8f535d6b0555a2aa43efbc9141e3dd7edaef8b1278ac34eabfc2db735d992ee")); }
void pbkdf2_long_message(void) { PBKDF2 pbkdf2(QString("ThisMessageIsLongerThanSixtyFourCharactersWhichLeadsToTheSituationThatTheMessageHasToBeHashedWhenCalculatingTheHmac").toUtf8(), QString("pepper").toUtf8(), 3, QCryptographicHash::Sha512); QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("efc8e734ed5b5657ac220046754b7d1dbea00983f13209b1ec1d0e418e98807cba1026d3ed3fa2a09dfa43c074447bf4777e70e4999d29d2c2f84dc51502a195")); }
void pbkdf2_sha384(void) { PBKDF2 pbkdf2(QString("message").toUtf8(), QString("salt").toUtf8(), 3, QCryptographicHash::Sha384); QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("dcbeb0b99a4cf4d1c9c1e8f630f3aa8637c8906f1c3e1c78fb4f462b160df20f7435bdd6a904dd3c3ede7ff04bc53e90")); }
void pbkdf2_sha256(void) { PBKDF2 pbkdf2(QString("message").toUtf8(), QString("salt").toUtf8(), 3, QCryptographicHash::Sha256); QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("db78c5091444940f9642fce519097ee7adfeb338fd6970855135539020b53fad")); }
int process_hdr(const char *dev, int flags, unsigned char *pass, int passlen, struct tchdr_enc *ehdr, struct tcplay_info **pinfo) { struct tchdr_dec *dhdr; struct tcplay_info *info; struct tc_cipher_chain *cipher_chain = NULL; unsigned char *key; int i, j, found, error; *pinfo = NULL; if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) { tc_log(1, "could not allocate safe key memory\n"); return ENOMEM; } /* Start search for correct algorithm combination */ found = 0; for (i = 0; !found && pbkdf_prf_algos[i].name != NULL; i++) { #ifdef DEBUG printf("\nTrying PRF algo %s (%d)\n", pbkdf_prf_algos[i].name, pbkdf_prf_algos[i].iteration_count); printf("Salt: "); print_hex(ehdr->salt, 0, sizeof(ehdr->salt)); #endif error = pbkdf2(&pbkdf_prf_algos[i], (char *)pass, passlen, ehdr->salt, sizeof(ehdr->salt), MAX_KEYSZ, key); if (error) { tc_log(1, "pbkdf failed for algorithm %s\n", pbkdf_prf_algos[i].name); free_safe_mem(key); return EINVAL; } #if 0 printf("Derived Key: "); print_hex(key, 0, MAX_KEYSZ); #endif for (j = 0; !found && tc_cipher_chains[j] != NULL; j++) { cipher_chain = tc_dup_cipher_chain(tc_cipher_chains[j]); #ifdef DEBUG printf("\nTrying cipher chain %d\n", j); #endif dhdr = decrypt_hdr(ehdr, cipher_chain, key); if (dhdr == NULL) { tc_log(1, "hdr decryption failed for cipher " "chain %d\n", j); free_safe_mem(key); return EINVAL; } if (verify_hdr(dhdr)) { #ifdef DEBUG printf("tc_str: %.4s, tc_ver: %d, tc_min_ver: %d, " "crc_keys: %d, sz_vol: %"PRIu64", " "off_mk_scope: %"PRIu64", sz_mk_scope: %"PRIu64", " "flags: %d, sec_sz: %d crc_dhdr: %d\n", dhdr->tc_str, dhdr->tc_ver, dhdr->tc_min_ver, dhdr->crc_keys, dhdr->sz_vol, dhdr->off_mk_scope, dhdr->sz_mk_scope, dhdr->flags, dhdr->sec_sz, dhdr->crc_dhdr); #endif found = 1; } else { free_safe_mem(dhdr); tc_free_cipher_chain(cipher_chain); } } } free_safe_mem(key); if (!found) return EINVAL; if ((info = new_info(dev, flags, cipher_chain, &pbkdf_prf_algos[i-1], dhdr, 0)) == NULL) { free_safe_mem(dhdr); return ENOMEM; } *pinfo = info; return 0; }
void AppleCSPSession::DeriveKey_PBKDF2( const Context &context, const CssmData &Param, CSSM_DATA *keyData) { /* validate algorithm-specific arguments */ /* Param must point to a CSSM_PKCS5_PBKDF2_PARAMS */ if(Param.Length != sizeof(CSSM_PKCS5_PBKDF2_PARAMS)) { errorLog0("DeriveKey_PBKDF2: Param wrong size\n"); CssmError::throwMe(CSSMERR_CSP_INVALID_INPUT_POINTER); } const CSSM_PKCS5_PBKDF2_PARAMS *pbkdf2Params = reinterpret_cast<const CSSM_PKCS5_PBKDF2_PARAMS *>(Param.Data); if(pbkdf2Params == NULL) { errorLog0("DeriveKey_PBKDF2: null Param.Data\n"); CssmError::throwMe(CSSMERR_CSP_INVALID_DATA); } /* Get passphrase from either baseKey or from CSSM_PKCS5_PBKDF2_PARAMS */ CssmKey *passKey = context.get<CssmKey>(CSSM_ATTRIBUTE_KEY); CSSM_SIZE passphraseLen = 0; uint8 *passphrase = NULL; if(passKey != NULL) { AppleCSPContext::symmetricKeyBits(context, *this, CSSM_ALGID_SECURE_PASSPHRASE, CSSM_KEYUSE_DERIVE, passphrase, passphraseLen); } else { passphraseLen = pbkdf2Params->Passphrase.Length; passphrase = pbkdf2Params->Passphrase.Data; } #if !ALLOW_ZERO_PASSWORD /* passphrase required */ if(passphrase == NULL) { errorLog0("DeriveKey_PBKDF2: null Passphrase\n"); CssmError::throwMe(CSSMERR_CSP_INVALID_DATA); } if(passphraseLen == 0) { /* FIXME - enforce minimum length? */ errorLog0("DeriveKey_PBKDF2: zero length passphrase\n"); CssmError::throwMe(CSSMERR_CSP_INVALID_INPUT_POINTER); } #endif /* ALLOW_ZERO_PASSWORD */ if(pbkdf2Params->PseudoRandomFunction != CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1) { errorLog0("DeriveKey_PBKDF2: invalid PRF\n"); CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); } /* salt, from context, required */ CssmData salt = context.get<CssmData>(CSSM_ATTRIBUTE_SALT, CSSMERR_CSP_MISSING_ATTR_SALT); if((salt.Data == NULL) || (salt.Length < PBKDF2_MIN_SALT)) { CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SALT); } /* iteration count, from context, required */ uint32 iterCount = context.getInt(CSSM_ATTRIBUTE_ITERATION_COUNT, CSSMERR_CSP_MISSING_ATTR_ITERATION_COUNT); if(iterCount < PBKDF2_MIN_ITER_CNT) { CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ITERATION_COUNT); } /* * allocate a temp buffer, length * = MAX (hLen, saltLen + 4) + 2 * hLen * = MAX (kSHA1DigestSize, saltLen + 4) + 2 * kSHA1DigestSize */ size_t tempLen = salt.Length + 4; if(tempLen < kSHA1DigestSize) { tempLen = kSHA1DigestSize; } tempLen += (2 * kSHA1DigestSize); CSSM_DATA tempData = {0, NULL}; setUpData(tempData, tempLen, privAllocator); /* go */ pbkdf2 (hmacsha1, kSHA1DigestSize, passphrase, (uint32)passphraseLen, salt.Data, (uint32)salt.Length, iterCount, keyData->Data, (uint32)keyData->Length, tempData.Data); freeData(&tempData, privAllocator, false); }
/* IF YOU CALL THIS MULTIPLE TIMES WITH THE SAME KEY YOU MUST PROVIDE AN IV POINTER! */ int crypt_data(const unsigned char *data_in, unsigned char *data_out, size_t data_size, const unsigned char *data_mkey, size_t data_mkey_size, unsigned char *data_new_hmac, const unsigned char *data_chk_hmac, size_t data_hmac_size, unsigned char **IV_start, int mode) { if (mode != MODE_ENCRYPT && mode != MODE_DECRYPT) { fprintf(stderr, "crypt_data called with invalid mode %d\n", mode); return -1; } symmetric_CTR ctr; #ifdef _POSIX_MEMLOCK_RANGE if (mlock(&ctr, sizeof(ctr)) != 0) { fprintf(stderr, "WARNING: mlock failed at %s:%d - ", __FILE__, __LINE__); perror(""); } #endif int err; int ret = 0; /* return code */ unsigned char *IV; unsigned long IV_size = 16; int hash_idx = find_hash("sha256"); size_t data_ckey_size, data_hkey_size; data_ckey_size = data_hkey_size = data_mkey_size; unsigned char *subkeys = safe_malloc(data_ckey_size + data_hkey_size); #ifdef _POSIX_MEMLOCK_RANGE if (mlock(subkeys, data_ckey_size + data_hkey_size) != 0) { fprintf(stderr, "WARNING: mlock failed at %s:%d - ", __FILE__, __LINE__); perror(""); } #endif unsigned char *data_ckey = subkeys + 0; unsigned char *data_hkey = subkeys + data_ckey_size; pbkdf2(data_mkey, data_mkey_size, "H", 1, SUBKEY_ITER, hash_idx, data_hkey, &data_hkey_size); pbkdf2(data_mkey, data_mkey_size, "C", 1, SUBKEY_ITER, hash_idx, data_ckey, &data_ckey_size); if (IV_start == NULL || *IV_start == NULL) { IV = safe_malloc(IV_size); /* fprintf(stderr, "Initializing key-based IV\n"); */ /* This is at least as secure as starting with a zeroed IV */ pbkdf2(data_mkey, data_mkey_size, "I", 1, SUBKEY_ITER, hash_idx, IV, &IV_size); } if (IV_start != NULL) { if (*IV_start != NULL) { /* fprintf(stderr, "IV = *IV_start\n"); */ IV = *IV_start; } else { /* fprintf(stderr, "*IV_start = IV\n"); */ *IV_start = IV; } } if (mode == MODE_DECRYPT && data_chk_hmac != NULL) { if ((err = hmac_vrfymem(hash_idx, data_hkey, data_hkey_size, data_in, data_size, data_chk_hmac, (long unsigned int *)&data_hmac_size)) != CRYPT_OK) { crypt_data_return(THRCR_BADMAC); } } /* LTC_CTR_RFC3686 is needed to avoid reusing a counter value. */ if ((err = ctr_start(find_cipher("aes"), IV, data_ckey, data_ckey_size, 0, CTR_COUNTER_BIG_ENDIAN | LTC_CTR_RFC3686, &ctr)) != CRYPT_OK) { fprintf(stderr, "Error initializing cipher: %d\n", err); crypt_data_return(-1); } /* ctr_encrypt is used for both encryption and decryption */ if ((err = ctr_encrypt(data_in, data_out, data_size, &ctr)) != CRYPT_OK) { fprintf(stderr, "ctr_encrypt error: %s\n", error_to_string(err)); ctr_done(&ctr); /* done with cipher, clean up keys */ crypt_data_return(-1); } ctr_done(&ctr); /* done with cipher, clean up keys */ if (mode == MODE_ENCRYPT && data_new_hmac != NULL) { if ((err = hmac_memory(hash_idx, data_hkey, data_hkey_size, data_out, data_size, data_new_hmac, (long unsigned int *)&data_hmac_size)) != CRYPT_OK) { fprintf(stderr, "hmac error: %s\n", error_to_string(err)); crypt_data_return(-1); } } crypt_data_return: /* before actually returning, make sure key material isn't in memory */ MEMWIPE(&ctr, sizeof(ctr)); MEMWIPE(subkeys, data_ckey_size + data_hkey_size); #ifdef _POSIX_MEMLOCK_RANGE munlock(subkeys, data_ckey_size + data_hkey_size); #endif safe_free(subkeys); /* save the IV */ if (IV_start != NULL && *IV_start != NULL) { /* fprintf(stderr, "*IV_start = ctr.ctr\n"); */ ctr_getiv(*IV_start, &IV_size, &ctr); } else { safe_free(IV); } return ret; }