internal abstract class SymmetricTransform : ICryptoTransform {
protected SymmetricAlgorithm algo;
protected bool encrypt;
- private int BlockSizeByte;
- private byte[] temp;
- private byte[] temp2;
+ protected int BlockSizeByte;
+ protected byte[] temp;
+ protected byte[] temp2;
private byte[] workBuff;
private byte[] workout;
-#if !NET_2_1 || MONOTOUCH
+#if !MOONLIGHT
// Silverlight 2.0 does not support any feedback mode
- private int FeedBackByte;
- private int FeedBackIter;
+ protected int FeedBackByte;
#endif
private bool m_disposed = false;
private bool lastBlock;
} else {
rgbIV = (byte[]) rgbIV.Clone ();
}
-#if NET_2_0
// compare the IV length with the "currently selected" block size and *ignore* IV that are too big
if (rgbIV.Length < BlockSizeByte) {
string msg = Locale.GetText ("IV is too small ({0} bytes), it should be {1} bytes long.",
rgbIV.Length, BlockSizeByte);
throw new CryptographicException (msg);
}
-#endif
// mode buffers
temp = new byte [BlockSizeByte];
Buffer.BlockCopy (rgbIV, 0, temp, 0, System.Math.Min (BlockSizeByte, rgbIV.Length));
temp2 = new byte [BlockSizeByte];
-#if !NET_2_1 || MONOTOUCH
+#if !MOONLIGHT
FeedBackByte = (algo.FeedbackSize >> 3);
- if (FeedBackByte != 0)
- FeedBackIter = (int) BlockSizeByte / FeedBackByte;
#endif
// transform buffers
workBuff = new byte [BlockSizeByte];
// i.e. Any padding must be done before calling this method
protected virtual void Transform (byte[] input, byte[] output)
{
-#if NET_2_1
+#if MOONLIGHT
// Silverlight 2.0 only supports CBC
CBC (input, output);
#else
}
}
-#if !NET_2_1 || MONOTOUCH
+#if !MOONLIGHT
// Cipher-FeedBack (CFB)
+ // this is how *CryptoServiceProvider implements CFB
+ // only AesCryptoServiceProvider support CFB > 8
+ // RijndaelManaged is incompatible with this implementation (and overrides it in it's own transform)
protected virtual void CFB (byte[] input, byte[] output)
{
if (encrypt) {
- for (int x = 0; x < FeedBackIter; x++) {
+ for (int x = 0; x < BlockSizeByte; x++) {
// temp is first initialized with the IV
ECB (temp, temp2);
- for (int i = 0; i < FeedBackByte; i++)
+ for (int i = 0; i < 1; i++)
output[i + x] = (byte)(temp2[i] ^ input[i + x]);
- Buffer.BlockCopy (temp, FeedBackByte, temp, 0, BlockSizeByte - FeedBackByte);
- Buffer.BlockCopy (output, x, temp, BlockSizeByte - FeedBackByte, FeedBackByte);
+ Buffer.BlockCopy (temp, 1, temp, 0, BlockSizeByte - 1);
+ Buffer.BlockCopy (output, x, temp, BlockSizeByte - 1, 1);
}
}
else {
- for (int x = 0; x < FeedBackIter; x++) {
+ for (int x = 0; x < BlockSizeByte; x++) {
// we do not really decrypt this data!
encrypt = true;
// temp is first initialized with the IV
ECB (temp, temp2);
encrypt = false;
- Buffer.BlockCopy (temp, FeedBackByte, temp, 0, BlockSizeByte - FeedBackByte);
- Buffer.BlockCopy (input, x, temp, BlockSizeByte - FeedBackByte, FeedBackByte);
- for (int i = 0; i < FeedBackByte; i++)
+ Buffer.BlockCopy (temp, 1, temp, 0, BlockSizeByte - 1);
+ Buffer.BlockCopy (input, x, temp, BlockSizeByte - 1, 1);
+ for (int i = 0; i < 1; i++)
output[i + x] = (byte)(temp2[i] ^ input[i + x]);
}
}
// ordered to avoid possible integer overflow
int len = outputBuffer.Length - inputCount - outputOffset;
-#if NET_2_1
+#if MOONLIGHT
// only PKCS7 is supported Silverlight 2.0
if (KeepLastBlock) {
#else
} else if (KeepLastBlock) {
#endif
if (0 > len + BlockSizeByte) {
-#if NET_2_0
throw new CryptographicException ("outputBuffer", Locale.GetText ("Overflow"));
-#else
- throw new IndexOutOfRangeException (Locale.GetText ("Overflow"));
-#endif
}
} else {
if (0 > len) {
private bool KeepLastBlock {
get {
-#if NET_2_1
+#if MOONLIGHT
// only PKCS7 is supported Silverlight 2.0
return !encrypt;
#else
return total;
}
-#if NET_2_0 && !NET_2_1 || MONOTOUCH
+#if !MOONLIGHT
RandomNumberGenerator _rng;
private void Random (byte[] buffer, int start, int length)
int rem = inputCount - full;
int total = full;
-#if NET_2_1
+#if MOONLIGHT
// only PKCS7 is supported Silverlight 2.0
total += BlockSizeByte;
#else
switch (algo.Padding) {
-#if NET_2_0
case PaddingMode.ANSIX923:
case PaddingMode.ISO10126:
-#endif
case PaddingMode.PKCS7:
// we need to add an extra block for padding
total += BlockSizeByte;
// now we only have a single last block to encrypt
byte padding = (byte) (BlockSizeByte - rem);
-#if NET_2_1
+#if MOONLIGHT
// only PKCS7 is supported Silverlight 2.0
for (int i = res.Length; --i >= (res.Length - padding);)
res [i] = padding;
InternalTransformBlock (res, full, BlockSizeByte, res, full);
#else
switch (algo.Padding) {
-#if NET_2_0
case PaddingMode.ANSIX923:
// XX 00 00 00 00 00 00 07 (zero + padding length)
res [res.Length - 1] = padding;
// the last padded block will be transformed in-place
InternalTransformBlock (res, full, BlockSizeByte, res, full);
break;
-#endif // NET_2_0
case PaddingMode.PKCS7:
// XX 07 07 07 07 07 07 07 (padding length)
for (int i = res.Length; --i >= (res.Length - padding);)
// total may be 0 (e.g. PaddingMode.None)
byte padding = ((total > 0) ? res [total - 1] : (byte) 0);
-#if NET_2_1
+#if MOONLIGHT
// only PKCS7 is supported Silverlight 2.0
if ((padding == 0) || (padding > BlockSizeByte))
throw new CryptographicException (Locale.GetText ("Bad padding length."));
total -= padding;
#else
switch (algo.Padding) {
-#if NET_2_0
case PaddingMode.ANSIX923:
if ((padding == 0) || (padding > BlockSizeByte))
ThrowBadPaddingException (algo.Padding, padding, -1);
}
total -= padding;
break;
-#else
- case PaddingMode.PKCS7:
- total -= padding;
- break;
-#endif // NET_2_0
case PaddingMode.None: // nothing to do - it's a multiple of block size
case PaddingMode.Zeros: // nothing to do - user must unpad himself
break;