[bcl] Add CommonCrypto to corlib, Mono.Security and System.Core.
[mono.git] / mcs / class / corlib / CommonCrypto / CryptorTransform.cs
1 // ICryptoTransform implementation on top of CommonCrypto and SymmetricTransform
2 //
3 // Authors:
4 //      Sebastien Pouliot  <sebastien@xamarin.com>
5 //
6 // Copyright 2012 Xamarin Inc.
7
8 using System;
9 using System.Security.Cryptography;
10
11 using Mono.Security.Cryptography;
12
13 namespace Crimson.CommonCrypto {
14
15         class CryptorTransform : SymmetricTransform {
16                 
17                 IntPtr handle;
18                 IntPtr handle_e;
19                 bool encryption;
20                 
21                 public CryptorTransform (IntPtr cryptor, IntPtr special, SymmetricAlgorithm algo, bool encryption, byte[] iv)
22                         : base (algo, encryption, iv)
23                 {
24                         handle = cryptor;
25                         // for CFB we need to encrypt data while decrypting
26                         handle_e = special;
27                         this.encryption = encryption;
28                 }
29                 
30                 ~CryptorTransform ()
31                 {
32                         Dispose (false);
33                 }
34                 
35                 // PRO: doing this ensure all cipher modes and padding modes supported by .NET will be available with CommonCrypto (drop-in replacements)
36                 // 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
37                 protected override void ECB (byte[] input, byte[] output)
38                 {
39                         IntPtr len = IntPtr.Zero;
40                         CCCryptorStatus s = Cryptor.CCCryptorUpdate ((encrypt == encryption) ? handle : handle_e, 
41                                 input, (IntPtr) input.Length, output, (IntPtr) output.Length, ref len);
42                         if (((int) len != output.Length) || (s != CCCryptorStatus.Success))
43                                 throw new CryptographicUnexpectedOperationException (s.ToString ());
44                 }
45                 
46                 protected override void Dispose (bool disposing)
47                 {
48                         if (handle != IntPtr.Zero) {
49                                 Cryptor.CCCryptorRelease (handle);
50                                 handle = IntPtr.Zero;
51                         }
52                         if (handle_e != IntPtr.Zero) {
53                                 Cryptor.CCCryptorRelease (handle_e);
54                                 handle_e = IntPtr.Zero;
55                         }
56                         base.Dispose (disposing);
57                         GC.SuppressFinalize (this);
58                 }
59         }
60 }