// helper method to reduce the amount of generate code for each cipher algorithm static internal IntPtr Create(CCOperation operation, CCAlgorithm algorithm, CCOptions options, byte[] key, byte[] iv) { if (key == null) { throw new CryptographicException("A null key was provided"); } // unlike the .NET framework CommonCrypto does not support two-keys triple-des (128 bits) ref: #6967 if ((algorithm == CCAlgorithm.TripleDES) && (key.Length == 16)) { byte[] key3 = new byte [24]; Buffer.BlockCopy(key, 0, key3, 0, 16); Buffer.BlockCopy(key, 0, key3, 16, 8); key = key3; } IntPtr cryptor = IntPtr.Zero; CCCryptorStatus status = Cryptor.CCCryptorCreate(operation, algorithm, options, key, (IntPtr)key.Length, iv, ref cryptor); if (status != CCCryptorStatus.Success) { throw new CryptographicUnexpectedOperationException(); } return(cryptor); }
// PRO: doing this ensure all cipher modes and padding modes supported by .NET will be available with CommonCrypto (drop-in replacements) // CON: doing this will only process one block at the time, so it's not ideal for performance, but still a lot better than managed protected override void ECB(byte[] input, byte[] output) { IntPtr len = IntPtr.Zero; CCCryptorStatus s = Cryptor.CCCryptorUpdate((encrypt == encryption) ? handle : handle_e, input, (IntPtr)input.Length, output, (IntPtr)output.Length, ref len); if (((int)len != output.Length) || (s != CCCryptorStatus.Success)) { throw new CryptographicUnexpectedOperationException(s.ToString()); } }
public unsafe int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { CheckInput(inputBuffer, inputOffset, inputCount); if (inputCount == 0) { return(0); } // check output parameters if (outputBuffer == null) { throw new ArgumentNullException("outputBuffer"); } if (outputOffset < 0) { throw new ArgumentOutOfRangeException("outputOffset", "< 0"); } // ordered to avoid possible integer overflow if (outputOffset > outputBuffer.Length - inputCount) { throw new ArgumentException("outputBuffer", "Overflow"); } if (outputBuffer.Length == 0) { throw new CryptographicException("output buffer too small"); } if (handle == IntPtr.Zero) { handle = Cryptor.Create(CCOperation.Encrypt, CCAlgorithm.RC4, CCOptions.None, KeyValue, IVValue); } IntPtr len = IntPtr.Zero; IntPtr in_len = (IntPtr)(inputBuffer.Length - inputOffset); IntPtr out_len = (IntPtr)(outputBuffer.Length - outputOffset); fixed(byte *input = &inputBuffer[0]) fixed(byte *output = &outputBuffer [0]) { CCCryptorStatus s = Cryptor.CCCryptorUpdate(handle, (IntPtr)(input + inputOffset), in_len, (IntPtr)(output + outputOffset), out_len, ref len); if ((len != out_len) || (s != CCCryptorStatus.Success)) { throw new CryptographicUnexpectedOperationException(s.ToString()); } } return((int)out_len); }
int Transform(byte[] input, int inputOffset, byte[] output, int outputOffset, int length) { IntPtr len = IntPtr.Zero; IntPtr in_len = (IntPtr)length; IntPtr out_len = (IntPtr)(output.Length - outputOffset); fixed(byte *inputBuffer = &input[0]) fixed(byte *outputBuffer = &output [0]) { CCCryptorStatus s = Cryptor.CCCryptorUpdate(handle, (IntPtr)(inputBuffer + inputOffset), in_len, (IntPtr)(outputBuffer + outputOffset), out_len, ref len); if (s != CCCryptorStatus.Success) { throw new CryptographicException(s.ToString()); } } return((int)len); }