Пример #1
0
/* Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal) */
int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
{
	int retVal = ERR_SUCCESS;

	switch (cipher)
	{
	case AES:
#ifndef TC_WINDOWS_BOOT
		if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
			return ERR_CIPHER_INIT_FAILURE;

		if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx))) != EXIT_SUCCESS)
			return ERR_CIPHER_INIT_FAILURE;
#else
		if (aes_set_key (key, (length_type) CipherGetKeySize(AES), (aes_context *) ks) != 0)
			return ERR_CIPHER_INIT_FAILURE;
#endif
		break;

	case SERPENT:
		serpent_set_key (key, ks);
		break;
		
	case TWOFISH:
		twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key);
		break;

	default:
		// Unknown/wrong cipher ID
		return ERR_CIPHER_INIT_FAILURE;
	}

	return retVal;
}
Пример #2
0
/* Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal) */
int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
{
	int retVal = ERR_SUCCESS;

	switch (cipher)
	{
	case AES:
#ifndef TC_WINDOWS_BOOT
		if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
			return ERR_CIPHER_INIT_FAILURE;

		if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx))) != EXIT_SUCCESS)
			return ERR_CIPHER_INIT_FAILURE;
#else
		if (aes_set_key (key, (length_type) CipherGetKeySize(AES), (aes_context *) ks) != 0)
			return ERR_CIPHER_INIT_FAILURE;
#endif
		break;

	case SERPENT:
		serpent_set_key (key, CipherGetKeySize(SERPENT) * 8, ks);
		break;
		
	case TWOFISH:
		twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, CipherGetKeySize(TWOFISH) * 8);
		break;

#ifndef TC_WINDOWS_BOOT
		
	case BLOWFISH:
		/* Deprecated/legacy */
		BlowfishSetKey ((BF_KEY *)ks, CipherGetKeySize(BLOWFISH), key);
		break;

	case CAST:
		/* Deprecated/legacy */
		Cast5SetKey ((CAST_KEY *) ks, CipherGetKeySize(CAST), key);
		break;

	case TRIPLEDES:
		/* Deprecated/legacy */
		TripleDesSetKey (key, CipherGetKeySize (TRIPLEDES), (TDES_KEY *) ks);

		// Verify whether all three DES keys are mutually different
		if (((*((__int64 *) key) ^ *((__int64 *) key+1)) & 0xFEFEFEFEFEFEFEFEULL) == 0
		|| ((*((__int64 *) key+1) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0
		|| ((*((__int64 *) key) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0)
			retVal = ERR_CIPHER_INIT_WEAK_KEY;		// Non-fatal error

		break;

#endif	// TC_WINDOWS_BOOT

	default:
		// Unknown/wrong cipher ID
		return ERR_CIPHER_INIT_FAILURE;
	}

	return retVal;
}
static void
do_serpent(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
{
    serpent_context serpent_ctx;
    char iv_bak[SERPENT_CBC_BLOCK_SIZE];
    char *new_iv = NULL;	/* logic will avoid copy to NULL */


    serpent_set_key(&serpent_ctx, key, key_size);
    /*	
     *	my SERPENT cbc does not touch passed IV (optimization for
     *	ESP handling), so I must "emulate" des-like IV
     *	crunching
     */
    if (!enc)
	    memcpy(new_iv=iv_bak, 
			    (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE,
			    SERPENT_CBC_BLOCK_SIZE);

    serpent_cbc_encrypt(&serpent_ctx, buf, buf, buf_size, iv, enc);

    if (enc)
	    new_iv = (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE;

    memcpy(iv, new_iv, SERPENT_CBC_BLOCK_SIZE);
}
Пример #4
0
int
serpent_xts_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
	struct serpent_xts_ctx *ctx;

	if (len != 32 && len != 64)
		return -1;

	*sched = kmalloc(sizeof(struct serpent_xts_ctx), M_CRYPTO_DATA,
	    M_WAITOK | M_ZERO);
	ctx = (struct serpent_xts_ctx *)*sched;

	serpent_set_key(&ctx->key1, key, len * 4);
	serpent_set_key(&ctx->key2, key + (len / 2), len * 4);

	return 0;
}
Пример #5
0
static int
serpent128_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
	int err;

	if (len != 16 && len != 24 && len != 32)
		return (EINVAL);
	*sched = kmalloc(sizeof(serpent_ctx), M_CRYPTO_DATA,
			 M_INTWAIT | M_ZERO);
	if (*sched != NULL) {
		serpent_set_key((serpent_ctx *) *sched, key, len * 8);
		err = 0;
	} else
		err = ENOMEM;
	return err;
}
Пример #6
0
int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
{
#ifdef GST_WINDOWS_BOOT_AES

	aes_init();

	if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
		return ERR_CIPHER_INIT_FAILURE;
	if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
		return ERR_CIPHER_INIT_FAILURE;

#elif defined (GST_WINDOWS_BOOT_SERPENT)
	serpent_set_key (key, 32 * 8, ks);
#elif defined (GST_WINDOWS_BOOT_TWOFISH)
	twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, 32 * 8);
#endif
	return ERR_SUCCESS;
}
Пример #7
0
static void do_serpent(u_int8_t *buf, size_t buf_size, PK11SymKey *key,
		       u_int8_t *iv, bool enc)
{
	serpent_context serpent_ctx;
	u_int8_t iv_bak[SERPENT_CBC_BLOCK_SIZE];
	u_int8_t *new_iv = buf + buf_size - SERPENT_CBC_BLOCK_SIZE;
	u_int8_t *bare_key_ptr;
	size_t bare_key_len;

	/* unpack key from PK11SymKey (or crash!) */
	{
		SECStatus status = PK11_ExtractKeyValue(key);
		SECItem *keydata;

		passert(status == SECSuccess);
		keydata = PK11_GetKeyData(key);
		bare_key_ptr = keydata->data;
		bare_key_len = keydata->len;
		// SECITEM_FreeItem(keydata, PR_TRUE);
	}

	serpent_set_key(&serpent_ctx, bare_key_ptr, bare_key_len);
	/*
	 *	my SERPENT cbc does not touch passed IV (optimization for
	 *	ESP handling), so I must "emulate" des-like IV
	 *	crunching
	 */
	if (!enc) {
		memcpy(iv_bak, new_iv, SERPENT_CBC_BLOCK_SIZE);
		new_iv = iv_bak;
	}

	serpent_cbc_encrypt(&serpent_ctx, buf, buf, buf_size, iv, enc);

	memcpy(iv, new_iv, SERPENT_CBC_BLOCK_SIZE);
}
Пример #8
0
	void CipherSerpent::SetCipherKey (const byte *key)
	{
		serpent_set_key (key, ScheduledKey);
	}
Пример #9
0
int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
{
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
    char dk[32 * 2];			// 2 * 256-bit key
#else
    char dk[32 * 2 * 3];		// 6 * 256-bit key
#endif

    PCRYPTO_INFO cryptoInfo;
    int status = ERR_SUCCESS;
    uint32 iterations = pim;
    iterations <<= 16;
    iterations |= bBoot;

    if (retHeaderCryptoInfo != NULL)
        cryptoInfo = retHeaderCryptoInfo;
    else
        cryptoInfo = *retInfo = crypto_open ();

    // PKCS5 PRF
#ifdef TC_WINDOWS_BOOT_SHA2
    derive_key_sha256 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
                       PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
#else
    derive_key_ripemd160 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
                          PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
#endif

    // Mode of operation
    cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;

#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
    cryptoInfo->ea = 1;
#else
    // Test all available encryption algorithms
    for (cryptoInfo->ea = EAGetFirst (); cryptoInfo->ea != 0; cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
#endif
    {
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
#if defined (TC_WINDOWS_BOOT_SERPENT)
        serpent_set_key (dk, cryptoInfo->ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
        twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
        camellia_set_key (dk, cryptoInfo->ks);
#else
        status = EAInit (dk, cryptoInfo->ks);
        if (status == ERR_CIPHER_INIT_FAILURE)
            goto err;
#endif
#else
        status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
        if (status == ERR_CIPHER_INIT_FAILURE)
            goto err;
#endif
        // Secondary key schedule
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
#if defined (TC_WINDOWS_BOOT_SERPENT)
        serpent_set_key (dk + 32, cryptoInfo->ks2);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
        twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
        camellia_set_key (dk + 32, cryptoInfo->ks2);
#else
        EAInit (dk + 32, cryptoInfo->ks2);
#endif
#else
        EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
#endif

        // Try to decrypt header
        DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

        // Check magic 'VERA' and CRC-32 of header fields and master keydata
        if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241
                || (GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION) >= 4 && GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
                || GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
        {
            EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
            status = ERR_PASSWORD_WRONG;
            goto err;
#else
            continue;
#endif
        }

        // Header decrypted
        status = 0;

        // Hidden volume status
        cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE);
        cryptoInfo->hiddenVolume = (cryptoInfo->VolumeSize.LowPart != 0 || cryptoInfo->VolumeSize.HighPart != 0);

        // Volume size
        cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);

        // Encrypted area size and length
        cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
        cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);

        // Flags
        cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);

#ifdef TC_WINDOWS_BOOT_SHA2
        cryptoInfo->pkcs5 = SHA256;
#else
        cryptoInfo->pkcs5 = RIPEMD160;
#endif

        memcpy (dk, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (dk));
        EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

        if (retHeaderCryptoInfo)
            goto ret;

        // Init the encryption algorithm with the decrypted master key
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
#if defined (TC_WINDOWS_BOOT_SERPENT)
        serpent_set_key (dk, cryptoInfo->ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
        twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
        camellia_set_key (dk, cryptoInfo->ks);
#else
        status = EAInit (dk, cryptoInfo->ks);
        if (status == ERR_CIPHER_INIT_FAILURE)
            goto err;
#endif
#else
        status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
        if (status == ERR_CIPHER_INIT_FAILURE)
            goto err;
#endif

        // The secondary master key (if cascade, multiple concatenated)
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
#if defined (TC_WINDOWS_BOOT_SERPENT)
        serpent_set_key (dk + 32, cryptoInfo->ks2);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
        twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
        camellia_set_key (dk + 32, cryptoInfo->ks2);
#else
        EAInit (dk + 32, cryptoInfo->ks2);
#endif
#else
        EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
#endif
        goto ret;
    }

    status = ERR_PASSWORD_WRONG;

err:
    if (cryptoInfo != retHeaderCryptoInfo)
    {
        crypto_close(cryptoInfo);
        *retInfo = NULL;
    }

ret:
    burn (dk, sizeof(dk));
    return status;
}