Example #1
0
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);
}
Example #3
0
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");
}
Example #4
0
// 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));
}
Example #5
0
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);
	}
Example #7
0
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);
}
Example #8
0
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));
}
Example #9
0
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), &sector,
		    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;
}
Example #10
0
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);
}
Example #11
0
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);
}
Example #13
0
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);
}
Example #14
0
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);
}
Example #15
0
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;
}
Example #16
0
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);    
}
Example #18
0
 void pbkdf2(void)
 {
   PBKDF2 pbkdf2(QString("message").toUtf8(), QString("pepper").toUtf8(), 3, QCryptographicHash::Sha512);
   QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("2646f9ccb58d21406815bafc62245771bf80aaa080a633ff1bdd660eb44f369a89da48fb041c5551a118de20cfb8b96b92e7a9945425ba889e9ad645614522eb"));
 }
Example #19
0
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;
}
Example #20
0
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;
}
Example #21
0
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;
    }
}
Example #22
0
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;
    }
}
Example #23
0
 void pbkdf2_empty_salt(void)
 {
   PBKDF2 pbkdf2(QString("message").toUtf8(), QByteArray(), 3, QCryptographicHash::Sha512);
   QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("b8ec13cfc9b9d49ca1143018ce8413a962c09c0063f30a466df802897475c57f268d91cc568ac1b6a9f19b1a0db10f30058fb7a453b2675010ef2b5f96487ad3"));
 }
Example #24
0
 void pbkdf2_empty_message(void)
 {
   PBKDF2 pbkdf2(SecureByteArray(), QString("pepper").toUtf8(), 3, QCryptographicHash::Sha512);
   QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("9dd331fc67421e1dce619cbbb517170e2dc325491d3426425630c4c01fd0eca8d8f535d6b0555a2aa43efbc9141e3dd7edaef8b1278ac34eabfc2db735d992ee"));
 }
Example #25
0
 void pbkdf2_long_message(void)
 {
   PBKDF2 pbkdf2(QString("ThisMessageIsLongerThanSixtyFourCharactersWhichLeadsToTheSituationThatTheMessageHasToBeHashedWhenCalculatingTheHmac").toUtf8(), QString("pepper").toUtf8(), 3, QCryptographicHash::Sha512);
   QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("efc8e734ed5b5657ac220046754b7d1dbea00983f13209b1ec1d0e418e98807cba1026d3ed3fa2a09dfa43c074447bf4777e70e4999d29d2c2f84dc51502a195"));
 }
Example #26
0
 void pbkdf2_sha384(void)
 {
   PBKDF2 pbkdf2(QString("message").toUtf8(), QString("salt").toUtf8(), 3, QCryptographicHash::Sha384);
   QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("dcbeb0b99a4cf4d1c9c1e8f630f3aa8637c8906f1c3e1c78fb4f462b160df20f7435bdd6a904dd3c3ede7ff04bc53e90"));
 }
Example #27
0
 void pbkdf2_sha256(void)
 {
   PBKDF2 pbkdf2(QString("message").toUtf8(), QString("salt").toUtf8(), 3, QCryptographicHash::Sha256);
   QVERIFY(pbkdf2.derivedKey() == QByteArray::fromHex("db78c5091444940f9642fce519097ee7adfeb338fd6970855135539020b53fad"));
 }
Example #28
0
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;
}
Example #29
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);
}
Example #30
0
/* 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;
}