1
0
mirror of https://github.com/wolfSSL/wolfssl.git synced 2026-10-24 04:09:07 +03:00
Files
wolfssl/wrapper/CSharp/wolfCrypt-FIPS/FipsHash.cs

178 lines
7.6 KiB
C#

/* FipsHash.cs
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
using System;
namespace wolfSSL.CSharp.Fips
{
/* Approved hashes in the v5.2.1 module. Values are its wc_HashType values (v5
* numbering, types.h), which are also the HMAC type identifiers. */
public enum FipsHashType
{
Sha1 = 4,
Sha224 = 5,
Sha256 = 6,
Sha384 = 7,
Sha512 = 8,
Sha3_224 = 10,
Sha3_256 = 11,
Sha3_384 = 12,
Sha3_512 = 13
}
/* Incremental message digest (SHA-1, SHA-2, SHA-3) from the FIPS module.
* After Final the object is reset and can hash a new message. */
public sealed class FipsHash : FipsObject
{
private const int INVALID_DEVID = -2;
public FipsHashType Type { get; }
public int DigestSize => DigestSizeOf(Type);
public FipsHash(FipsHashType type) : base(StructOf(type))
{
Type = type;
int ret = Init(type, Handle);
if (ret != 0)
{
Dispose();
throw new WolfCryptFipsException(type == FipsHashType.Sha1 ? "wc_InitSha_fips" : "wc_Init" + type + "_fips", ret);
}
SetNativeFree(FreeRoutine(type));
}
public void Update(byte[] data)
{
if (data == null)
{
throw new ArgumentNullException(nameof(data));
}
ThrowIfDisposed();
WolfCryptFipsException.Check(Type + " update", Update(Type, Handle, data, (uint)data.Length));
}
/* Returns the digest and resets the object for a new message. */
public byte[] Final()
{
ThrowIfDisposed();
byte[] digest = new byte[DigestSize];
WolfCryptFipsException.Check(Type + " final", Final(Type, Handle, digest));
return digest;
}
/* One-shot digest of data. */
public static byte[] Compute(FipsHashType type, byte[] data)
{
using var h = new FipsHash(type);
h.Update(data);
return h.Final();
}
public static int DigestSizeOf(FipsHashType type) => type switch
{
FipsHashType.Sha1 => 20,
FipsHashType.Sha224 or FipsHashType.Sha3_224 => 28,
FipsHashType.Sha256 or FipsHashType.Sha3_256 => 32,
FipsHashType.Sha384 or FipsHashType.Sha3_384 => 48,
FipsHashType.Sha512 or FipsHashType.Sha3_512 => 64,
_ => throw new ArgumentOutOfRangeException(nameof(type))
};
private static FipsStructType StructOf(FipsHashType type) => type switch
{
FipsHashType.Sha1 => FipsStructType.Sha,
FipsHashType.Sha224 => FipsStructType.Sha224,
FipsHashType.Sha256 => FipsStructType.Sha256,
FipsHashType.Sha384 => FipsStructType.Sha384,
FipsHashType.Sha512 => FipsStructType.Sha512,
FipsHashType.Sha3_224 or FipsHashType.Sha3_256 or
FipsHashType.Sha3_384 or FipsHashType.Sha3_512 => FipsStructType.Sha3,
_ => throw new ArgumentOutOfRangeException(nameof(type))
};
private static int Init(FipsHashType t, FipsHandle h)
{
switch (t)
{
case FipsHashType.Sha1: return Native.wc_InitSha_fips(h);
case FipsHashType.Sha224: return Native.wc_InitSha224_fips(h);
case FipsHashType.Sha256: return Native.wc_InitSha256_fips(h);
case FipsHashType.Sha384: return Native.wc_InitSha384_fips(h);
case FipsHashType.Sha512: return Native.wc_InitSha512_fips(h);
case FipsHashType.Sha3_224: return Native.wc_InitSha3_224_fips(h, IntPtr.Zero, INVALID_DEVID);
case FipsHashType.Sha3_256: return Native.wc_InitSha3_256_fips(h, IntPtr.Zero, INVALID_DEVID);
case FipsHashType.Sha3_384: return Native.wc_InitSha3_384_fips(h, IntPtr.Zero, INVALID_DEVID);
case FipsHashType.Sha3_512: return Native.wc_InitSha3_512_fips(h, IntPtr.Zero, INVALID_DEVID);
default: throw new ArgumentOutOfRangeException(nameof(t));
}
}
private static int Update(FipsHashType t, FipsHandle h, byte[] d, uint len)
{
switch (t)
{
case FipsHashType.Sha1: return Native.wc_ShaUpdate_fips(h, d, len);
case FipsHashType.Sha224: return Native.wc_Sha224Update_fips(h, d, len);
case FipsHashType.Sha256: return Native.wc_Sha256Update_fips(h, d, len);
case FipsHashType.Sha384: return Native.wc_Sha384Update_fips(h, d, len);
case FipsHashType.Sha512: return Native.wc_Sha512Update_fips(h, d, len);
case FipsHashType.Sha3_224: return Native.wc_Sha3_224_Update_fips(h, d, len);
case FipsHashType.Sha3_256: return Native.wc_Sha3_256_Update_fips(h, d, len);
case FipsHashType.Sha3_384: return Native.wc_Sha3_384_Update_fips(h, d, len);
case FipsHashType.Sha3_512: return Native.wc_Sha3_512_Update_fips(h, d, len);
default: throw new ArgumentOutOfRangeException(nameof(t));
}
}
private static int Final(FipsHashType t, FipsHandle h, byte[] o)
{
switch (t)
{
case FipsHashType.Sha1: return Native.wc_ShaFinal_fips(h, o);
case FipsHashType.Sha224: return Native.wc_Sha224Final_fips(h, o);
case FipsHashType.Sha256: return Native.wc_Sha256Final_fips(h, o);
case FipsHashType.Sha384: return Native.wc_Sha384Final_fips(h, o);
case FipsHashType.Sha512: return Native.wc_Sha512Final_fips(h, o);
case FipsHashType.Sha3_224: return Native.wc_Sha3_224_Final_fips(h, o);
case FipsHashType.Sha3_256: return Native.wc_Sha3_256_Final_fips(h, o);
case FipsHashType.Sha3_384: return Native.wc_Sha3_384_Final_fips(h, o);
case FipsHashType.Sha3_512: return Native.wc_Sha3_512_Final_fips(h, o);
default: throw new ArgumentOutOfRangeException(nameof(t));
}
}
private static Action<IntPtr> FreeRoutine(FipsHashType t) => t switch
{
FipsHashType.Sha1 => p => Native.wc_ShaFree_fips(p),
FipsHashType.Sha224 => p => Native.wc_Sha224Free_fips(p),
FipsHashType.Sha256 => p => Native.wc_Sha256Free_fips(p),
FipsHashType.Sha384 => p => Native.wc_Sha384Free_fips(p),
FipsHashType.Sha512 => p => Native.wc_Sha512Free_fips(p),
FipsHashType.Sha3_224 => p => Native.wc_Sha3_224_Free_fips(p),
FipsHashType.Sha3_256 => p => Native.wc_Sha3_256_Free_fips(p),
FipsHashType.Sha3_384 => p => Native.wc_Sha3_384_Free_fips(p),
FipsHashType.Sha3_512 => p => Native.wc_Sha3_512_Free_fips(p),
_ => throw new ArgumentOutOfRangeException(nameof(t))
};
}
}