[Mono-bugs] [Bug 345510] New: CryptoStream ignores the ICryptoTransform. CanTransformMultipleBlocks property when reading

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Mon Dec 3 07:47:44 EST 2007


           Summary: CryptoStream ignores the
                    ICryptoTransform.CanTransformMultipleBlocks property
                    when reading
           Product: Mono: Class Libraries
           Version: SVN
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: security
          Severity: Major
          Priority: P5 - None
         Component: CORLIB
        AssignedTo: mono-bugs at ximian.com
        ReportedBy: lordhabbit at gmail.com
         QAContact: mono-bugs at ximian.com
          Found By: Third Party Developer/Partner

As the summary specifies, the CryptoStream.Read method ignores the
CanTransformMultipleBlocks property of its associated ICryptoTransform, which
makes it always transform blocks one by one, that is, ICT.InputBlockSize bytes
at a time.
This behaviour, though not optimal, is usually OK for encryption algorithms,
whose block sizes are usually around 16-64 bytes. However, hash algorithms can
also be used in a CryptoStream (they don't affect the data passing through
them, just hash it and make the result available in their Hash property), but
their InputBlockSize is fixed at 1 byte regardless of the true implementation
block size because they buffer data.
This brings about the doomsday scenario where trying to hash a 3MB file (which
takes less than .1 secs with sha1sum, IO time included) results in _at least_
three million calls* to ICryptoTransform.TransformBlock and a similar amount to
Buffer.BlockCopy. In other words: both CryptoStream and the hash algorithm are
buffering the data, having fun creating, copying and moving around millions of
1-byte arrays. In fact, 63 out of 64 calls to SHA1Managed.TransformBlock did
nothing else than buffer one more byte and return. The speed penalty is
massive, as hashing the file took nearly 2 seconds. This makes the CS+HAlg
combination _unusable_ for its usual purposes, i.e. checking large streams of

THUS: given than HashAlgorithm.InputBlockSize is fixed at 1 for MS
compatibility, CryptoStream.Read needs to take full advantage of transforms
that can much multiple "blocks" in a single call to TransformBlock (as are hash
algorithms). This is not as easy as it seems, as one always needs to know
whether the underlying stream has reached its end in order to call
TransformFinalBlock, but it is performance-critical. Both the full MS
implementation and the Mono CS.Write method do it fine.

* All figures about calls were obtained using mono --profile. Elapsed times
were measured _without_ the --profile option.

Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.

More information about the mono-bugs mailing list