Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Core / System / Security / Cryptography / ECDiffieHellman.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6
7 using System;
8 using System.Runtime.Serialization;
9
10 namespace System.Security.Cryptography {
11     /// <summary>
12     ///     Abstract base class for implementations of elliptic curve Diffie-Hellman to derive from
13     /// </summary>
14     [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
15     public abstract class ECDiffieHellman : AsymmetricAlgorithm {
16         public override string KeyExchangeAlgorithm {
17             get { return "ECDiffieHellman"; }
18         }
19
20         public override string SignatureAlgorithm {
21             get { return null; }
22         }
23
24         //
25         // Creation factory methods
26         //
27
28         public static new ECDiffieHellman Create() {
29 #if MONO
30             throw new NotImplementedException ();
31 #else
32             return Create(typeof(ECDiffieHellmanCng).FullName);
33 #endif
34         }
35
36         public static new ECDiffieHellman Create(string algorithm) {
37             if (algorithm == null) {
38                 throw new ArgumentNullException("algorithm");
39             }
40
41             return CryptoConfig.CreateFromName(algorithm) as ECDiffieHellman;
42         }
43
44         /// <summary>
45         /// Creates a new instance of the default implementation of the Elliptic Curve Diffie-Hellman Algorithm
46         /// (ECDH) with a newly generated key over the specified curve.
47         /// </summary>
48         /// <param name="curve">The curve to use for key generation.</param>
49         /// <returns>A new instance of the default implementation of this class.</returns>
50         public static ECDiffieHellman Create(ECCurve curve)
51         {
52             ECDiffieHellman ecdh = Create();
53
54             if (ecdh != null) {
55                 try {
56                     ecdh.GenerateKey(curve);
57                 }
58                 catch {
59                     ecdh.Dispose();
60                     throw;
61                 }
62             }
63
64             return ecdh;
65         }
66
67         /// <summary>
68         /// Creates a new instance of the default implementation of the Elliptic Curve Diffie-Hellman Algorithm
69         /// (ECDH) using the specified ECParameters as the key.
70         /// </summary>
71         /// <param name="parameters">The parameters representing the key to use.</param>
72         /// <returns>A new instance of the default implementation of this class.</returns>
73         public static ECDiffieHellman Create(ECParameters parameters)
74         {
75             ECDiffieHellman ecdh = Create();
76
77             if (ecdh != null) {
78                 try {
79                     ecdh.ImportParameters(parameters);
80                 }
81                 catch {
82                     ecdh.Dispose();
83                     throw;
84                 }
85             }
86
87             return ecdh;
88         }
89
90         //
91         // Key derivation
92         //
93
94         public abstract ECDiffieHellmanPublicKey PublicKey { get; }
95
96         // This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract.
97         public virtual byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey)
98         {
99             throw DerivedClassMustOverride();
100         }
101
102         /// <summary>
103         /// Derive key material using the formula HASH(x) where x is the computed result of the EC Diffie-Hellman algorithm.
104         /// </summary>
105         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
106         /// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
107         /// <returns>A hashed output suitable for key material</returns>
108         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
109         public byte[] DeriveKeyFromHash(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm)
110         {
111             return DeriveKeyFromHash(otherPartyPublicKey, hashAlgorithm, null, null);
112         }
113
114         /// <summary>
115         /// Derive key material using the formula HASH(secretPrepend || x || secretAppend) where x is the computed
116         /// result of the EC Diffie-Hellman algorithm.
117         /// </summary>
118         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
119         /// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
120         /// <param name="secretPrepend">A value to prepend to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
121         /// <param name="secretAppend">A value to append to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
122         /// <returns>A hashed output suitable for key material</returns>
123         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
124         public virtual byte[] DeriveKeyFromHash(
125             ECDiffieHellmanPublicKey otherPartyPublicKey,
126             HashAlgorithmName hashAlgorithm,
127             byte[] secretPrepend,
128             byte[] secretAppend)
129         {
130             throw DerivedClassMustOverride();
131         }
132
133         /// <summary>
134         /// Derive key material using the formula HMAC(hmacKey, x) where x is the computed
135         /// result of the EC Diffie-Hellman algorithm.
136         /// </summary>
137         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
138         /// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
139         /// <param name="hmacKey">The key to use in the HMAC. A <c>null</c> value indicates that the result of the EC Diffie-Hellman algorithm should be used as the HMAC key.</param>
140         /// <returns>A hashed output suitable for key material</returns>
141         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
142         public byte[] DeriveKeyFromHmac(
143             ECDiffieHellmanPublicKey otherPartyPublicKey,
144             HashAlgorithmName hashAlgorithm,
145             byte[] hmacKey)
146         {
147             return DeriveKeyFromHmac(otherPartyPublicKey, hashAlgorithm, hmacKey, null, null);
148         }
149
150         /// <summary>
151         /// Derive key material using the formula HMAC(hmacKey, secretPrepend || x || secretAppend) where x is the computed
152         /// result of the EC Diffie-Hellman algorithm.
153         /// </summary>
154         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
155         /// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
156         /// <param name="hmacKey">The key to use in the HMAC. A <c>null</c> value indicates that the result of the EC Diffie-Hellman algorithm should be used as the HMAC key.</param>
157         /// <param name="secretPrepend">A value to prepend to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
158         /// <param name="secretAppend">A value to append to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
159         /// <returns>A hashed output suitable for key material</returns>
160         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
161         public virtual byte[] DeriveKeyFromHmac(
162             ECDiffieHellmanPublicKey otherPartyPublicKey,
163             HashAlgorithmName hashAlgorithm,
164             byte[] hmacKey,
165             byte[] secretPrepend,
166             byte[] secretAppend)
167         {
168             throw DerivedClassMustOverride();
169         }
170
171         /// <summary>
172         /// Derive key material using the TLS pseudo-random function (PRF) derivation algorithm.
173         /// </summary>
174         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
175         /// <param name="prfLabel">The ASCII encoded PRF label.</param>
176         /// <param name="prfSeed">The 64-byte PRF seed.</param>
177         /// <returns>A 48-byte output of the TLS pseudo-random function.</returns>
178         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
179         /// <exception cref="ArgumentNullException"><paramref name="prfLabel"/> is null</exception>
180         /// <exception cref="ArgumentNullException"><paramref name="prfSeed"/> is null</exception>
181         /// <exception cref="CryptographicException"><paramref name="prfSeed"/> is not exactly 64 bytes in length</exception>
182         public virtual byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed)
183         {
184             throw DerivedClassMustOverride();
185         }
186
187         private static Exception DerivedClassMustOverride()
188         {
189             return new NotImplementedException(SR.GetString(SR.NotSupported_SubclassOverride));
190         }
191
192         /// <summary>
193         /// When overridden in a derived class, exports the named or explicit ECParameters for an ECCurve.
194         /// If the curve has a name, the Curve property will contain named curve parameters, otherwise it
195         /// will contain explicit parameters.
196         /// </summary>
197         /// <param name="includePrivateParameters">true to include private parameters, otherwise, false.</param>
198         /// <returns>The ECParameters representing the point on the curve for this key.</returns>
199         public virtual ECParameters ExportParameters(bool includePrivateParameters)
200         {
201             throw DerivedClassMustOverride();
202         }
203
204         /// <summary>
205         /// When overridden in a derived class, exports the explicit ECParameters for an ECCurve.
206         /// </summary>
207         /// <param name="includePrivateParameters">true to include private parameters, otherwise, false.</param>
208         /// <returns>The ECParameters representing the point on the curve for this key, using the explicit curve format.</returns>
209         public virtual ECParameters ExportExplicitParameters(bool includePrivateParameters)
210         {
211             throw DerivedClassMustOverride();
212         }
213
214         /// <summary>
215         /// When overridden in a derived class, imports the specified ECParameters.
216         /// </summary>
217         /// <param name="parameters">The curve parameters.</param>
218         public virtual void ImportParameters(ECParameters parameters)
219         {
220             throw DerivedClassMustOverride();
221         }
222
223         /// <summary>
224         /// When overridden in a derived class, generates a new public/private keypair for the specified curve.
225         /// </summary>
226         /// <param name="curve">The curve to use.</param>
227         public virtual void GenerateKey(ECCurve curve)
228         {
229             throw new NotSupportedException(SR.GetString(SR.NotSupported_SubclassOverride));
230         }
231     }
232 }