1

In the C# implementation of the salsa20, if I call the method TransformBlock two times on a block of size 1, it is different than calling it a single time on a block of size 2, this is problematic when you use this class to encrypt objects sent via BinaryFormatter.

Is this by design?

To remedy this I wrapped salsa20 in another class (decorator design pattern) that generates and caches blocks of 64 bytes at a time, basically like this (in simplified pseudo-code):

private Queue<byte> queue;
private ICryptoTransform salsa20CryptoTransform;
public int TransformBlock(byte[] input, byte[] output){
    while(input.Length > queue.Count){
        byte[] temp1 = new byte[64];
        byte[] temp2 = new byte[64];
        salsa20CryptoTransform.TransformBlock(temp1, temp2);
        foreach(byte b in  temp2){
            queue.Enqueue(b);
        }
    }
    for(int i = 0;i<input.Length;i++){
        output[i] = intput[i] ^ queue.Dequeue();
    }
}

Is there anything I should be concerned about here in terms of security?

Morad
  • 734
  • 5
  • 14
  • Sounds like a bug in the implementation you're using. `TransformBlock` should have no relation to underlying blocks. – CodesInChaos Sep 11 '13 at 18:48

1 Answers1

1

Blocks are blocks; a lot of compression and encryption processes have special demarcation of blocks, where they essentially reset a few things - making a block a unit (potentially also the minimal unit that can be unscrambled - an important consideration for streaming APIs). The important question, though, is not "is the encrypted data the same" - frankly, it doesn't need to be. In many cases, it would be entirely legitimate if it encrypted it differently every time you called it (via some internal randomisation). The only important question is:

If I decrypt this appropriately, with the correct keys: do I get back the original data?

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Actually, it is almost always *desirable* that the encrypted data is different every time the encryption function is called – this is what initialization vectors and nonces are for. – ntoskrnl Sep 07 '13 at 17:47
  • I'm pretty sure that `TransformBlock` should have no relation to the underlying blocks. It's used to process chunks of a size the caller chooses and its the duty of the underlying implementation to split it into blocks as it needs. The way you split the data between multiple `TransformBlock`s and the final `TransformFinalBlock` should have no effect on the result. IVs don't change between blocks either. You first fix key and nonce, and then get an arbitrary length stream as output which gets xor-ed into the plaintext. – CodesInChaos Sep 11 '13 at 18:49