Occasionally, for instance in very constrained environment, it can be useful to use only a few cryptographic primitives for all processing. (When you only have a hammer everything looks like a nail.)
In such environments, it may be useful to use key derivation function to derive stream to be used as a stream cipher, or use hash function as cipher and so on.
However, using primitives in non-standard ways risks implementation mistakes and often is "path less traveled", thus risking vulnerabilities that were not thought of.
EncryptedData = Concat(DataBlock XOR Whirlpool(DataBlock + SecretKey))
Have you thought of decrypting data encrypted this way? The DataBlock is supposedly to be kept as a secret, but Whirlpool takes it as input. Thus, to decrypt EncryptedData, it is necessary to know DataBlock.
A pretty well examines way of using hash function based on cipher function as cipher is SHACAL-2. SHACAL(-2) is one of the most well examined "hash-function turned into cipher" constructs. It has been used with SHA-1 and SHA-2 hash functions. It would be possible to use similar construct to turn (some implementations of) Whirlpool into a forward cipher function, and then use that in, in counter mode.
If it is mandatory to use entire Whirlpool function (above "WhirlpoolCAL" construct would not use padding part of hash function), then you could, for instance, use key derivation construct as stream cipher. See NIST SP 800-108 Recommendation for Key Derivation Functions using Pseudorandom Functions. The document shows a few ways that could be used to construct keys stream using a hash function (approved hash functions are SHA family, but here you would use Whirlpool). Note the NIST SP 800-108 requires HMAC construct to build keyed hash function from hash function.
That document also warns against idea of using the function as stream cipher:
"To comply with this Recommendation, the derived keying material shall not be used as a key stream for a stream cipher2.
2 The level of security provided by using the key derivation functions specified in this Recommendation to generate a key stream for stream ciphers has not been investigated."
So summary is, that you "could" do it like this:
EncryptedData = Data XOR KDF(HMAC(Whirlpool))
Where KDF is implemented using the following process (see the above mentioned document SP800-108 for full details).
Process:
- n := ⎡L/h⎤.
- If n > 2r-1, then indicate an error and stop.
- result(0):= ∅.
- For i = 1 to n, do
a. K(i) := PRF (KI, [i]2 || Label || 0x00 || Context || [L]2) 12
b. result(i) := result(i-1) || K(i).
- Return: KO := the leftmost L bits of result(n).
But: The comment above from Stephen Touset, the SP 800-108 document, and this answer also, are all warning against doing it this way. Use good cipher like AES (or maybe Camellia or ARIA or whatever) in appropriate mode for symmetric encryption and decryption needs and avoid home-baked cryptography.
(AES-CTR if you want to use XOR and no message integrity. AES-GCM is typically even better idea.)
DataBlock XOR hash
step might interfere with their feed-forward operation. – CodesInChaos Sep 23 '13 at 11:39