Merge pull request #3389 from lambdageek/bug-43099
[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         //
45         // Key derivation
46         //
47
48         public abstract ECDiffieHellmanPublicKey PublicKey { get; }
49
50         // This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract.
51         public virtual byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey)
52         {
53             throw DerivedClassMustOverride();
54         }
55
56         /// <summary>
57         /// Derive key material using the formula HASH(x) where x is the computed result of the EC Diffie-Hellman algorithm.
58         /// </summary>
59         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
60         /// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
61         /// <returns>A hashed output suitable for key material</returns>
62         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
63         public byte[] DeriveKeyFromHash(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm)
64         {
65             return DeriveKeyFromHash(otherPartyPublicKey, hashAlgorithm, null, null);
66         }
67
68         /// <summary>
69         /// Derive key material using the formula HASH(secretPrepend || x || secretAppend) where x is the computed
70         /// result of the EC Diffie-Hellman algorithm.
71         /// </summary>
72         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
73         /// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
74         /// <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>
75         /// <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>
76         /// <returns>A hashed output suitable for key material</returns>
77         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
78         public virtual byte[] DeriveKeyFromHash(
79             ECDiffieHellmanPublicKey otherPartyPublicKey,
80             HashAlgorithmName hashAlgorithm,
81             byte[] secretPrepend,
82             byte[] secretAppend)
83         {
84             throw DerivedClassMustOverride();
85         }
86
87         /// <summary>
88         /// Derive key material using the formula HMAC(hmacKey, x) where x is the computed
89         /// result of the EC Diffie-Hellman algorithm.
90         /// </summary>
91         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
92         /// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
93         /// <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>
94         /// <returns>A hashed output suitable for key material</returns>
95         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
96         public byte[] DeriveKeyFromHmac(
97             ECDiffieHellmanPublicKey otherPartyPublicKey,
98             HashAlgorithmName hashAlgorithm,
99             byte[] hmacKey)
100         {
101             return DeriveKeyFromHmac(otherPartyPublicKey, hashAlgorithm, hmacKey, null, null);
102         }
103
104         /// <summary>
105         /// Derive key material using the formula HMAC(hmacKey, secretPrepend || x || secretAppend) where x is the computed
106         /// result of the EC Diffie-Hellman algorithm.
107         /// </summary>
108         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
109         /// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
110         /// <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>
111         /// <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>
112         /// <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>
113         /// <returns>A hashed output suitable for key material</returns>
114         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
115         public virtual byte[] DeriveKeyFromHmac(
116             ECDiffieHellmanPublicKey otherPartyPublicKey,
117             HashAlgorithmName hashAlgorithm,
118             byte[] hmacKey,
119             byte[] secretPrepend,
120             byte[] secretAppend)
121         {
122             throw DerivedClassMustOverride();
123         }
124
125         /// <summary>
126         /// Derive key material using the TLS pseudo-random function (PRF) derivation algorithm.
127         /// </summary>
128         /// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
129         /// <param name="prfLabel">The ASCII encoded PRF label.</param>
130         /// <param name="prfSeed">The 64-byte PRF seed.</param>
131         /// <returns>A 48-byte output of the TLS pseudo-random function.</returns>
132         /// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
133         /// <exception cref="ArgumentNullException"><paramref name="prfLabel"/> is null</exception>
134         /// <exception cref="ArgumentNullException"><paramref name="prfSeed"/> is null</exception>
135         /// <exception cref="CryptographicException"><paramref name="prfSeed"/> is not exactly 64 bytes in length</exception>
136         public virtual byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed)
137         {
138             throw DerivedClassMustOverride();
139         }
140
141         private static Exception DerivedClassMustOverride()
142         {
143             return new NotImplementedException(SR.GetString(SR.NotSupported_SubclassOverride));
144         }
145     }
146 }