/* 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; }
/* 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_twofish(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc) { twofish_context twofish_ctx; char iv_bak[TWOFISH_CBC_BLOCK_SIZE]; char *new_iv = NULL; /* logic will avoid copy to NULL */ twofish_set_key(&twofish_ctx, key, key_size); /* * my TWOFISH 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 - TWOFISH_CBC_BLOCK_SIZE, TWOFISH_CBC_BLOCK_SIZE); } twofish_cbc_encrypt(&twofish_ctx, buf, buf, buf_size, iv, enc); if (enc) new_iv = (char*) buf + buf_size - TWOFISH_CBC_BLOCK_SIZE; memcpy(iv, new_iv, TWOFISH_CBC_BLOCK_SIZE); }
int twofish_xts_setkey(u_int8_t **sched, u_int8_t *key, int len) { struct twofish_xts_ctx *ctx; if (len != 32 && len != 64) return -1; *sched = kmalloc(sizeof(struct twofish_xts_ctx), M_CRYPTO_DATA, M_WAITOK | M_ZERO); ctx = (struct twofish_xts_ctx *)*sched; twofish_set_key(&ctx->key1, key, len * 4); twofish_set_key(&ctx->key2, key + (len / 2), len * 4); return 0; }
static int twofish128_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(twofish_ctx), M_CRYPTO_DATA, M_INTWAIT | M_ZERO); if (*sched != NULL) { twofish_set_key((twofish_ctx *) *sched, key, len * 8); err = 0; } else err = ENOMEM; return err; }
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; }
void CipherTwofish::SetCipherKey (const byte *key) { twofish_set_key ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *) key); }
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; }
/* Encrypt one block. in and out may be the same. */ int twofish_encrypt(cipher_context_t *context, uint8_t *in, uint8_t *out) { int res; //setup the twofish-specific context twofish_context_t *ctx = malloc(sizeof(twofish_context_t)); if (!ctx) { printf("%-40s: [ERROR] Could NOT malloc space for the twofish_context_t \ struct.\r\n", __FUNCTION__); return -1; } res = twofish_set_key(ctx, context->context, TWOFISH_KEY_SIZE); if (res < 0) { printf("%-40s: [ERROR] twofish_setKey failed with Code %i\r\n", __FUNCTION__, res); free(ctx); return -2; } /* The four 32-bit chunks of the text. */ uint32_t a, b, c, d; /* Temporaries used by the round function. */ /* cppcheck: used in macros in sys/include/crypto/twofish.h that cppcheck * doesn't understand */