AwsCryptographyPrimitives/runtimes/net/Extern/HMAC.cs (85 lines of code) (raw):
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
using System;
using System.Collections.Immutable;
using Wrappers_Compile;
using software.amazon.cryptography.primitives.internaldafny.types;
using Org.BouncyCastle.Math;
using ibyteseq = Dafny.ISequence<byte>;
using byteseq = Dafny.Sequence<byte>;
using _IDigestAlgorithm = software.amazon.cryptography.primitives.internaldafny.types._IDigestAlgorithm;
using Error_Opaque = software.amazon.cryptography.primitives.internaldafny.types.Error_Opaque;
namespace HMAC
{
public partial class __default
{
public static _IResult<ibyteseq, _IError> Digest(_IHMacInput input)
{
var maybeHmac = HMac.Build(input.dtor_digestAlgorithm);
if (maybeHmac.is_Failure)
{
return (maybeHmac).PropagateFailure<Dafny.ISequence<byte>>();
}
var hmac = maybeHmac.Extract();
hmac.Init(input.dtor_key);
hmac.BlockUpdate(input.dtor_message);
return Result<ibyteseq, _IError>.create_Success(hmac.GetResult());
}
}
public partial class HMac
{
private Org.BouncyCastle.Crypto.Macs.HMac hmac;
public static _IResult<HMac, _IError> Build(_IDigestAlgorithm digest)
{
try
{
return Result<HMac, _IError>.create_Success(new HMac(digest));
}
catch (Exception ex)
{
return Wrappers_Compile.Result<HMac, _IError>
.create_Failure(AWS.Cryptography.Primitives.TypeConversion.ToDafny_CommonError(ex));
}
}
public HMac(_IDigestAlgorithm digest)
{
Org.BouncyCastle.Crypto.IDigest bouncyCastleDigest;
if (digest.is_SHA__256)
{
bouncyCastleDigest = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();
}
else if (digest.is_SHA__384)
{
bouncyCastleDigest = new Org.BouncyCastle.Crypto.Digests.Sha384Digest();
}
else if (digest.is_SHA__512)
{
bouncyCastleDigest = new Org.BouncyCastle.Crypto.Digests.Sha512Digest();
}
else
{
throw new System.Exception(String.Format("Unsupported digest: {0}", digest.ToString()));
}
hmac = new Org.BouncyCastle.Crypto.Macs.HMac(bouncyCastleDigest);
}
public void Init(ibyteseq input)
{
// KeyParameter/ Init should not mutate input, but this is safer than using input.Elements directly
byte[] elemCopy = (byte[])input.Elements.Clone();
var keyParams = new Org.BouncyCastle.Crypto.Parameters.KeyParameter(elemCopy);
hmac.Init(keyParams);
// elemCopy may contain sensitive info; zeroize it to reduce time this lives in memory
Array.Clear(elemCopy, 0, elemCopy.Length);
elemCopy = null;
}
public void BlockUpdate(ibyteseq input)
{
// BlockUpdate should not mutate input, but this is safer than using input.Elements directly
byte[] elemCopy = (byte[])input.Elements.Clone();
hmac.BlockUpdate(elemCopy, 0, elemCopy.Length);
// elemCopy may contain sensitive info; zeroize it to reduce time this lives in memory
Array.Clear(elemCopy, 0, elemCopy.Length);
elemCopy = null;
}
public ibyteseq GetResult()
{
byte[] output = new byte[hmac.GetMacSize()];
hmac.DoFinal(output, 0);
return byteseq.FromArray(output);
}
}
}