diff options
Diffstat (limited to 'crypto/src/security/MacUtilities.cs')
-rw-r--r-- | crypto/src/security/MacUtilities.cs | 212 |
1 files changed, 137 insertions, 75 deletions
diff --git a/crypto/src/security/MacUtilities.cs b/crypto/src/security/MacUtilities.cs index 9490616be..76b2ed353 100644 --- a/crypto/src/security/MacUtilities.cs +++ b/crypto/src/security/MacUtilities.cs @@ -5,6 +5,7 @@ using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Iana; using Org.BouncyCastle.Asn1.Misc; using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Rosstandart; using Org.BouncyCastle.Crypto; @@ -21,69 +22,133 @@ namespace Org.BouncyCastle.Security /// </remarks> public static class MacUtilities { - private static readonly IDictionary<string, string> Algorithms = + private static readonly Dictionary<string, string> AlgorithmMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + private static readonly Dictionary<DerObjectIdentifier, string> AlgorithmOidMap = + new Dictionary<DerObjectIdentifier, string>(); static MacUtilities() { - Algorithms[IanaObjectIdentifiers.HmacMD5.Id] = "HMAC-MD5"; - Algorithms[IanaObjectIdentifiers.HmacRipeMD160.Id] = "HMAC-RIPEMD160"; - Algorithms[IanaObjectIdentifiers.HmacSha1.Id] = "HMAC-SHA1"; - Algorithms[IanaObjectIdentifiers.HmacTiger.Id] = "HMAC-TIGER"; - - Algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "HMAC-SHA1"; - Algorithms[MiscObjectIdentifiers.HMAC_SHA1.Id] = "HMAC-SHA1"; - Algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "HMAC-SHA224"; - Algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "HMAC-SHA256"; - Algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "HMAC-SHA384"; - Algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "HMAC-SHA512"; - - Algorithms[NistObjectIdentifiers.IdHMacWithSha3_224.Id] = "HMAC-SHA3-224"; - Algorithms[NistObjectIdentifiers.IdHMacWithSha3_256.Id] = "HMAC-SHA3-256"; - Algorithms[NistObjectIdentifiers.IdHMacWithSha3_384.Id] = "HMAC-SHA3-384"; - Algorithms[NistObjectIdentifiers.IdHMacWithSha3_512.Id] = "HMAC-SHA3-512"; - - Algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256.Id] = "HMAC-GOST3411-2012-256"; - Algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512.Id] = "HMAC-GOST3411-2012-512"; + AlgorithmOidMap[IanaObjectIdentifiers.HmacMD5] = "HMAC-MD5"; + AlgorithmOidMap[IanaObjectIdentifiers.HmacRipeMD160] = "HMAC-RIPEMD160"; + AlgorithmOidMap[IanaObjectIdentifiers.HmacSha1] = "HMAC-SHA1"; + AlgorithmOidMap[IanaObjectIdentifiers.HmacTiger] = "HMAC-TIGER"; + + AlgorithmOidMap[PkcsObjectIdentifiers.IdHmacWithSha1] = "HMAC-SHA1"; + AlgorithmOidMap[MiscObjectIdentifiers.HMAC_SHA1] = "HMAC-SHA1"; + AlgorithmOidMap[PkcsObjectIdentifiers.IdHmacWithSha224] = "HMAC-SHA224"; + AlgorithmOidMap[PkcsObjectIdentifiers.IdHmacWithSha256] = "HMAC-SHA256"; + AlgorithmOidMap[PkcsObjectIdentifiers.IdHmacWithSha384] = "HMAC-SHA384"; + AlgorithmOidMap[PkcsObjectIdentifiers.IdHmacWithSha512] = "HMAC-SHA512"; + + AlgorithmOidMap[NistObjectIdentifiers.IdHMacWithSha3_224] = "HMAC-SHA3-224"; + AlgorithmOidMap[NistObjectIdentifiers.IdHMacWithSha3_256] = "HMAC-SHA3-256"; + AlgorithmOidMap[NistObjectIdentifiers.IdHMacWithSha3_384] = "HMAC-SHA3-384"; + AlgorithmOidMap[NistObjectIdentifiers.IdHMacWithSha3_512] = "HMAC-SHA3-512"; + + AlgorithmOidMap[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256] = "HMAC-GOST3411-2012-256"; + AlgorithmOidMap[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512] = "HMAC-GOST3411-2012-512"; // TODO AESMAC? - Algorithms["DES"] = "DESMAC"; - Algorithms["DES/CFB8"] = "DESMAC/CFB8"; - Algorithms["DES64"] = "DESMAC64"; - Algorithms["DESEDE"] = "DESEDEMAC"; - Algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDEMAC"; - Algorithms["DESEDE/CFB8"] = "DESEDEMAC/CFB8"; - Algorithms["DESISO9797MAC"] = "DESWITHISO9797"; - Algorithms["DESEDE64"] = "DESEDEMAC64"; - - Algorithms["DESEDE64WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; - Algorithms["DESEDEISO9797ALG1MACWITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; - Algorithms["DESEDEISO9797ALG1WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; - - Algorithms["ISO9797ALG3"] = "ISO9797ALG3MAC"; - Algorithms["ISO9797ALG3MACWITHISO7816-4PADDING"] = "ISO9797ALG3WITHISO7816-4PADDING"; - - Algorithms["SKIPJACK"] = "SKIPJACKMAC"; - Algorithms["SKIPJACK/CFB8"] = "SKIPJACKMAC/CFB8"; - Algorithms["IDEA"] = "IDEAMAC"; - Algorithms["IDEA/CFB8"] = "IDEAMAC/CFB8"; - Algorithms["RC2"] = "RC2MAC"; - Algorithms["RC2/CFB8"] = "RC2MAC/CFB8"; - Algorithms["RC5"] = "RC5MAC"; - Algorithms["RC5/CFB8"] = "RC5MAC/CFB8"; - Algorithms["GOST28147"] = "GOST28147MAC"; - Algorithms["VMPC"] = "VMPCMAC"; - Algorithms["VMPC-MAC"] = "VMPCMAC"; - Algorithms["SIPHASH"] = "SIPHASH-2-4"; - - Algorithms["PBEWITHHMACSHA"] = "PBEWITHHMACSHA1"; - Algorithms["1.3.14.3.2.26"] = "PBEWITHHMACSHA1"; + AlgorithmMap["DES"] = "DESMAC"; + AlgorithmMap["DES/CFB8"] = "DESMAC/CFB8"; + AlgorithmMap["DES64"] = "DESMAC64"; + AlgorithmMap["DESEDE"] = "DESEDEMAC"; + AlgorithmOidMap[PkcsObjectIdentifiers.DesEde3Cbc] = "DESEDEMAC"; + AlgorithmMap["DESEDE/CFB8"] = "DESEDEMAC/CFB8"; + AlgorithmMap["DESISO9797MAC"] = "DESWITHISO9797"; + AlgorithmMap["DESEDE64"] = "DESEDEMAC64"; + + AlgorithmMap["DESEDE64WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; + AlgorithmMap["DESEDEISO9797ALG1MACWITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; + AlgorithmMap["DESEDEISO9797ALG1WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; + + AlgorithmMap["ISO9797ALG3"] = "ISO9797ALG3MAC"; + AlgorithmMap["ISO9797ALG3MACWITHISO7816-4PADDING"] = "ISO9797ALG3WITHISO7816-4PADDING"; + + AlgorithmMap["SKIPJACK"] = "SKIPJACKMAC"; + AlgorithmMap["SKIPJACK/CFB8"] = "SKIPJACKMAC/CFB8"; + AlgorithmMap["IDEA"] = "IDEAMAC"; + AlgorithmMap["IDEA/CFB8"] = "IDEAMAC/CFB8"; + AlgorithmMap["RC2"] = "RC2MAC"; + AlgorithmMap["RC2/CFB8"] = "RC2MAC/CFB8"; + AlgorithmMap["RC5"] = "RC5MAC"; + AlgorithmMap["RC5/CFB8"] = "RC5MAC/CFB8"; + AlgorithmMap["GOST28147"] = "GOST28147MAC"; + AlgorithmMap["VMPC"] = "VMPCMAC"; + AlgorithmMap["VMPC-MAC"] = "VMPCMAC"; + AlgorithmMap["SIPHASH"] = "SIPHASH-2-4"; + + AlgorithmMap["PBEWITHHMACSHA"] = "PBEWITHHMACSHA1"; + AlgorithmOidMap[OiwObjectIdentifiers.IdSha1] = "PBEWITHHMACSHA1"; + +#if DEBUG + foreach (var key in AlgorithmMap.Keys) + { + if (DerObjectIdentifier.TryFromID(key, out var ignore)) + throw new Exception("OID mapping belongs in AlgorithmOidMap: " + key); + } + + var mechanisms = new HashSet<string>(AlgorithmMap.Values); + mechanisms.UnionWith(AlgorithmOidMap.Values); + + foreach (var mechanism in mechanisms) + { + if (AlgorithmMap.TryGetValue(mechanism, out var check)) + { + if (mechanism != check) + throw new Exception("Mechanism mapping MUST be to self: " + mechanism); + } + else + { + if (!mechanism.Equals(mechanism.ToUpperInvariant())) + throw new Exception("Unmapped mechanism MUST be uppercase: " + mechanism); + } + } +#endif + } + + public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[] input) + { + IMac mac = GetMac(algorithm); + mac.Init(cp); + mac.BlockUpdate(input, 0, input.Length); + return DoFinal(mac); + } + + public static byte[] DoFinal(IMac mac) + { + byte[] b = new byte[mac.GetMacSize()]; + mac.DoFinal(b, 0); + return b; + } + + public static byte[] DoFinal(IMac mac, byte[] input) + { + mac.BlockUpdate(input, 0, input.Length); + return DoFinal(mac); + } + + public static string GetAlgorithmName(DerObjectIdentifier oid) + { + return CollectionUtilities.GetValueOrNull(AlgorithmOidMap, oid); } + // TODO[api] Change parameter name to 'oid' public static IMac GetMac(DerObjectIdentifier id) { - return GetMac(id.Id); + if (id == null) + throw new ArgumentNullException(nameof(id)); + + if (AlgorithmOidMap.TryGetValue(id, out var mechanism)) + { + var mac = GetMacForMechanism(mechanism); + if (mac != null) + return mac; + } + + throw new SecurityUtilityException("Mac OID not recognised."); } public static IMac GetMac(string algorithm) @@ -91,8 +156,17 @@ namespace Org.BouncyCastle.Security if (algorithm == null) throw new ArgumentNullException(nameof(algorithm)); - string mechanism = CollectionUtilities.GetValueOrKey(Algorithms, algorithm).ToUpperInvariant(); + string mechanism = GetMechanism(algorithm) ?? algorithm.ToUpperInvariant(); + + var mac = GetMacForMechanism(mechanism); + if (mac != null) + return mac; + throw new SecurityUtilityException("Mac " + algorithm + " not recognised."); + } + + private static IMac GetMacForMechanism(string mechanism) + { if (Platform.StartsWith(mechanism, "PBEWITH")) { mechanism = mechanism.Substring("PBEWITH".Length); @@ -202,33 +276,21 @@ namespace Org.BouncyCastle.Security { return new SipHash(); } - throw new SecurityUtilityException("Mac " + mechanism + " not recognised."); + return null; } - public static string GetAlgorithmName(DerObjectIdentifier oid) + private static string GetMechanism(string algorithm) { - return CollectionUtilities.GetValueOrNull(Algorithms, oid.Id); - } + if (AlgorithmMap.TryGetValue(algorithm, out var mechanism1)) + return mechanism1; - public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[] input) - { - IMac mac = GetMac(algorithm); - mac.Init(cp); - mac.BlockUpdate(input, 0, input.Length); - return DoFinal(mac); - } - - public static byte[] DoFinal(IMac mac) - { - byte[] b = new byte[mac.GetMacSize()]; - mac.DoFinal(b, 0); - return b; - } + if (DerObjectIdentifier.TryFromID(algorithm, out var oid)) + { + if (AlgorithmOidMap.TryGetValue(oid, out var mechanism2)) + return mechanism2; + } - public static byte[] DoFinal(IMac mac, byte[] input) - { - mac.BlockUpdate(input, 0, input.Length); - return DoFinal(mac); + return null; } } } |