[bcl] Add CommonCrypto to corlib, Mono.Security and System.Core.
[mono.git] / mcs / class / corlib / CommonCrypto / CommonDigestGenerator.cs
1 //
2 // CommonCrypto code generator for digest algorithms
3 //
4 // Authors:
5 //      Sebastien Pouliot  <sebastien@xamarin.com>
6 //
7 // Copyright 2012-2014 Xamarin Inc.
8 //
9
10 using System;
11 using System.IO;
12
13 namespace Xamarin {
14
15         public static class CommonDigest {
16                 
17 #if !MONOTOUCH && !XAMMAC
18                 // we do not add anything in MonoTouch, just replacing, so this is not needed
19                 // however we can avoid a dependency on Mono.Security for Crimson.CommonCrypto.dll by including the base classes
20                 static public void GenerateBaseClass (string namespaceName, string typeName, string baseTypeName, int hashSize,
21                         string visibilityStart = "", string visibilityEnd = "")
22                 {
23                         string template = @"// Generated file to bind CommonCrypto/CommonDigest - DO NOT EDIT
24 //
25 // Authors:
26 //      Sebastien Pouliot  <sebastien@xamarin.com>
27 //
28 // Copyright 2012-2014 Xamarin Inc.
29
30 using System;
31 using System.Security.Cryptography;
32 using System.Runtime.InteropServices;
33
34 namespace %NAMESPACE% {
35
36 %VISIBILITY_START%
37         public
38 %VISIBILITY_END%
39         abstract class %BASE% : HashAlgorithm {
40
41                 protected %BASE% () 
42                 {
43                         HashSizeValue = %HASHSIZE%; 
44                 }
45
46                 public static new %BASE% Create ()
47                 {
48                         return Create (""%BASE%"");
49                 }
50
51                 public static new %BASE% Create (string hashName)
52                 {
53                         object o = CryptoConfig.CreateFromName (hashName);
54                         return (%BASE%) o ?? new %TYPE% ();
55                 }
56         }
57 }";
58                         
59                         File.WriteAllText (baseTypeName + ".g.cs", template.Replace ("%NAMESPACE%", namespaceName).
60                                 Replace ("%TYPE%", typeName).Replace ("%BASE%", baseTypeName).
61                                 Replace ("%VISIBILITY_START%", visibilityStart).Replace ("%VISIBILITY_END%", visibilityEnd).
62                                 Replace ("%HASHSIZE%", hashSize.ToString ()));
63                 }
64 #endif
65                 static public void Generate (string namespaceName, string typeName, string baseTypeName, int contextSize,
66                         string visibilityStart = "", string visibilityEnd = "")
67                 {
68                         string template = @"// Generated file to bind CommonCrypto/CommonDigest - DO NOT EDIT
69 //
70 // Authors:
71 //      Sebastien Pouliot  <sebastien@xamarin.com>
72 //
73 // Copyright 2011-2014 Xamarin Inc.
74
75 using System;
76 using System.Security.Cryptography;
77 using System.Runtime.InteropServices;
78
79 using Mono.Security.Cryptography;
80
81 namespace %NAMESPACE% {
82
83 %VISIBILITY_START%
84         public
85 %VISIBILITY_END%
86         sealed class %TYPE% : %BASE% {
87
88                 IntPtr ctx;
89
90                 [DllImport (""/usr/lib/libSystem.dylib"", EntryPoint=""CC_%BASE%_Init"")]
91                 static extern int Init (/* CC_%BASE%_CTX */ IntPtr c);
92
93                 [DllImport (""/usr/lib/libSystem.dylib"", EntryPoint=""CC_%BASE%_Update"")]
94                 static extern int Update (/* CC_%BASE%_CTX */ IntPtr c, /* const void * */ IntPtr data, /* uint32_t */ uint len);
95
96                 [DllImport (""/usr/lib/libSystem.dylib"", EntryPoint=""CC_%BASE%_Final"")]
97                 static extern int Final (/* unsigned char * */ byte [] md, /* CC_%BASE%_CTX */ IntPtr c);
98
99                 public %TYPE% ()
100                 {
101                         ctx = IntPtr.Zero;
102                 }
103
104                 ~%TYPE% ()
105                 {
106                         Dispose (false);
107                 }
108
109                 protected override void Dispose (bool disposing)
110                 {
111                         if (ctx != IntPtr.Zero) {
112                                 Marshal.FreeHGlobal (ctx);
113                                 ctx = IntPtr.Zero;
114                         }
115                         base.Dispose (disposing);
116                         GC.SuppressFinalize (this);
117                 }
118
119                 public override void Initialize ()
120                 {
121                         if (ctx == IntPtr.Zero)
122                                 ctx = Marshal.AllocHGlobal (%CTX_SIZE%);
123                         
124                         int hr = Init (ctx);
125                         if (hr != 1)
126                                 throw new CryptographicException (hr);
127                 }
128
129                 protected override void HashCore (byte[] data, int start, int length) 
130                 {
131                         if (ctx == IntPtr.Zero)
132                                 Initialize ();
133
134                         if (data.Length == 0)
135                                 return;
136
137                         unsafe {
138                                 fixed (byte* p = &data [0]) {
139                                         int hr = Update (ctx, (IntPtr) (p + start), (uint) length);
140                                         if (hr != 1)
141                                                 throw new CryptographicException (hr);
142                                 }
143                         }
144                 }
145
146                 protected override byte[] HashFinal () 
147                 {
148                         if (ctx == IntPtr.Zero)
149                                 Initialize ();
150                         
151                         byte[] data = new byte [HashSize >> 3];
152                         int hr = Final (data, ctx);
153                         if (hr != 1)
154                                 throw new CryptographicException (hr);
155
156                         return data;
157                 }
158         }
159 }";
160                         
161                         File.WriteAllText (typeName + ".g.cs", template.Replace ("%NAMESPACE%", namespaceName).
162                                 Replace ("%TYPE%", typeName).Replace ("%BASE%", baseTypeName).
163                                 Replace ("%VISIBILITY_START%", visibilityStart).Replace ("%VISIBILITY_END%", visibilityEnd).
164                                 Replace ("%CTX_SIZE%", contextSize.ToString ()));
165                 }
166         }
167 }