1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Diagnostics; 7 using System.Security.Cryptography; 8 9 using Internal.Cryptography; 10 11 namespace System.Security.Cryptography 12 { 13 // 14 // If you change anything in this class, you must make the same change in the other HMAC* classes. This is a pain but given that the 15 // preexisting contract from the desktop locks all of these into deriving directly from HMAC, it can't be helped. 16 // 17 18 public class HMACSHA512 : HMAC 19 { HMACSHA512()20 public HMACSHA512() 21 : this(Helpers.GenerateRandom(BlockSize)) 22 { 23 } 24 HMACSHA512(byte[] key)25 public HMACSHA512(byte[] key) 26 { 27 this.HashName = HashAlgorithmNames.SHA512; 28 _hMacCommon = new HMACCommon(HashAlgorithmNames.SHA512, key, BlockSize); 29 base.Key = _hMacCommon.ActualKey; 30 // change the default value of BlockSizeValue to 128 instead of 64 31 BlockSizeValue = BlockSize; 32 HashSizeValue = _hMacCommon.HashSizeInBits; 33 } 34 35 public bool ProduceLegacyHmacValues 36 { 37 get 38 { 39 return false; 40 } 41 set 42 { 43 if (value) 44 { 45 throw new PlatformNotSupportedException(); // This relates to a quirk in the Desktop managed implementation; ours is native. 46 } 47 } 48 } 49 50 public override byte[] Key 51 { 52 get 53 { 54 return base.Key; 55 } 56 set 57 { 58 _hMacCommon.ChangeKey(value); 59 base.Key = _hMacCommon.ActualKey; 60 } 61 } 62 HashCore(byte[] rgb, int ib, int cb)63 protected override void HashCore(byte[] rgb, int ib, int cb) => 64 _hMacCommon.AppendHashData(rgb, ib, cb); 65 66 protected override void HashCore(ReadOnlySpan<byte> source) => 67 _hMacCommon.AppendHashData(source); 68 HashFinal()69 protected override byte[] HashFinal() => 70 _hMacCommon.FinalizeHashAndReset(); 71 TryHashFinal(Span<byte> destination, out int bytesWritten)72 protected override bool TryHashFinal(Span<byte> destination, out int bytesWritten) => 73 _hMacCommon.TryFinalizeHashAndReset(destination, out bytesWritten); 74 Initialize()75 public override void Initialize() 76 { 77 // Nothing to do here. We expect HashAlgorithm to invoke HashFinal() and Initialize() as a pair. This reflects the 78 // reality that our native crypto providers (e.g. CNG) expose hash finalization and object reinitialization as an atomic operation. 79 } 80 Dispose(bool disposing)81 protected override void Dispose(bool disposing) 82 { 83 if (disposing) 84 { 85 HMACCommon hMacCommon = _hMacCommon; 86 if (hMacCommon != null) 87 { 88 _hMacCommon = null; 89 hMacCommon.Dispose(disposing); 90 } 91 } 92 base.Dispose(disposing); 93 } 94 95 private HMACCommon _hMacCommon; 96 private const int BlockSize = 128; 97 } 98 } 99