diff --git a/crypto/src/security/CipherUtilities.cs b/crypto/src/security/CipherUtilities.cs
index 6a53c7a8e..152e6dd69 100644
--- a/crypto/src/security/CipherUtilities.cs
+++ b/crypto/src/security/CipherUtilities.cs
@@ -24,8 +24,21 @@
namespace Org.BouncyCastle.Security
{
+ ///
+ /// Factory for instances, resolved from a textual algorithm name (with optional
+ /// mode/padding components) or from an ASN.1 algorithm OID.
+ ///
///
- /// Cipher Utility class contains methods that can not be specifically grouped into other classes.
+ ///
+ /// Algorithm strings follow the JCA-style ALGORITHM[/MODE[/PADDING]] convention (for example
+ /// "AES/CBC/PKCS7Padding" or "DESEDE/ECB/NoPadding"). Aliases for common algorithm names and
+ /// many standard ASN.1 OIDs are recognised. When the input cannot be resolved, a
+ /// is thrown.
+ ///
+ ///
+ /// The returned is uninitialised; the caller must invoke
+ /// before processing data.
+ ///
///
public static class CipherUtilities
{
@@ -295,11 +308,25 @@ static CipherUtilities()
#endif
}
+ ///
+ /// Returns the canonical algorithm name registered for the given ASN.1 OID, or null if the OID
+ /// is not mapped to a known cipher.
+ ///
+ /// An ASN.1 algorithm identifier.
+ /// The canonical algorithm name (suitable for passing to ),
+ /// or null.
public static string GetAlgorithmName(DerObjectIdentifier oid)
{
return CollectionUtilities.GetValueOrNull(AlgorithmOidMap, oid);
}
+ ///
+ /// Resolve and instantiate an for the given ASN.1 algorithm OID.
+ ///
+ /// The algorithm OID to look up.
+ /// A new, uninitialised .
+ /// If is null.
+ /// If the OID does not map to a known cipher.
public static IBufferedCipher GetCipher(DerObjectIdentifier oid)
{
if (oid == null)
@@ -315,6 +342,16 @@ public static IBufferedCipher GetCipher(DerObjectIdentifier oid)
throw new SecurityUtilityException("Cipher OID not recognised.");
}
+ ///
+ /// Resolve and instantiate an for the given algorithm specification.
+ ///
+ /// A JCA-style cipher name of the form ALGORITHM[/MODE[/PADDING]]
+ /// (e.g. "AES/CBC/PKCS7Padding"). Aliases such as "DESede" or "3DES" are
+ /// also accepted.
+ /// A new, uninitialised .
+ /// If is null.
+ /// If the algorithm, mode, or padding component is not
+ /// recognised.
public static IBufferedCipher GetCipher(string algorithm)
{
if (algorithm == null)
diff --git a/crypto/src/security/DigestUtilities.cs b/crypto/src/security/DigestUtilities.cs
index 68131a54d..d0bfc408d 100644
--- a/crypto/src/security/DigestUtilities.cs
+++ b/crypto/src/security/DigestUtilities.cs
@@ -18,8 +18,12 @@
namespace Org.BouncyCastle.Security
{
+ ///
+ /// Factory for instances and convenience helpers for one-shot hash computation.
+ ///
///
- /// Utility class for creating IDigest objects from their names/Oids
+ /// Digests can be looked up by canonical name (e.g. "SHA-256", "SHA3-512") or by ASN.1 OID.
+ /// Names are matched case-insensitively and a number of common aliases are recognised.
///
public static class DigestUtilities
{
@@ -202,18 +206,24 @@ static DigestUtilities()
#endif
}
+ /// One-shot digest of using the algorithm identified by
+ /// .
// TODO[api] Change parameter name to 'oid'
public static byte[] CalculateDigest(DerObjectIdentifier id, byte[] input)
{
return CalculateDigest(id.Id, input);
}
+ /// One-shot digest of using the named algorithm.
+ /// If is not recognised.
public static byte[] CalculateDigest(string algorithm, byte[] input)
{
IDigest digest = GetDigest(algorithm);
return DoFinal(digest, input);
}
+ /// One-shot digest of bytes from starting at
+ /// offset .
public static byte[] CalculateDigest(string algorithm, byte[] buf, int off, int len)
{
IDigest digest = GetDigest(algorithm);
@@ -221,9 +231,12 @@ public static byte[] CalculateDigest(string algorithm, byte[] buf, int off, int
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ /// One-shot digest of using the algorithm identified by
+ /// .
public static byte[] CalculateDigest(DerObjectIdentifier oid, ReadOnlySpan buffer) =>
CalculateDigest(oid.GetID(), buffer);
+ /// One-shot digest of using the named algorithm.
public static byte[] CalculateDigest(string algorithm, ReadOnlySpan buffer)
{
IDigest digest = GetDigest(algorithm);
@@ -231,6 +244,7 @@ public static byte[] CalculateDigest(string algorithm, ReadOnlySpan buffer
}
#endif
+ /// Finalises and returns the resulting hash as a fresh array.
public static byte[] DoFinal(IDigest digest)
{
byte[] b = new byte[digest.GetDigestSize()];
@@ -238,12 +252,16 @@ public static byte[] DoFinal(IDigest digest)
return b;
}
+ /// Feeds into , then finalises and returns the
+ /// hash.
public static byte[] DoFinal(IDigest digest, byte[] input)
{
digest.BlockUpdate(input, 0, input.Length);
return DoFinal(digest);
}
+ /// Feeds bytes from at offset
+ /// into , then finalises and returns the hash.
public static byte[] DoFinal(IDigest digest, byte[] buf, int off, int len)
{
digest.BlockUpdate(buf, off, len);
@@ -251,6 +269,8 @@ public static byte[] DoFinal(IDigest digest, byte[] buf, int off, int len)
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ /// Feeds into , then finalises and returns
+ /// the hash.
public static byte[] DoFinal(IDigest digest, ReadOnlySpan buffer)
{
digest.BlockUpdate(buffer);
@@ -258,11 +278,20 @@ public static byte[] DoFinal(IDigest digest, ReadOnlySpan buffer)
}
#endif
+ ///
+ /// Returns the canonical algorithm name registered for the given ASN.1 OID, or null if the OID
+ /// is not mapped to a known digest.
+ ///
public static string GetAlgorithmName(DerObjectIdentifier oid)
{
return CollectionUtilities.GetValueOrNull(AlgorithmOidMap, oid);
}
+ ///
+ /// Resolve and instantiate an for the given ASN.1 algorithm OID.
+ ///
+ /// If is null.
+ /// If the OID does not map to a known digest.
// TODO[api] Change parameter name to 'oid'
public static IDigest GetDigest(DerObjectIdentifier id)
{
@@ -279,6 +308,13 @@ public static IDigest GetDigest(DerObjectIdentifier id)
throw new SecurityUtilityException("Digest OID not recognised.");
}
+ ///
+ /// Resolve and instantiate an by name (or alias).
+ ///
+ /// A digest name (e.g. "SHA-256", "SHA3-512",
+ /// "BLAKE2B-512").
+ /// If is null.
+ /// If the digest name is not recognised.
public static IDigest GetDigest(string algorithm)
{
if (algorithm == null)
@@ -364,10 +400,11 @@ private static string GetMechanism(string algorithm)
}
///
- /// Returns an ObjectIdentifier for a given digest mechanism.
+ /// Returns the ASN.1 OID associated with the named digest mechanism, or null when none is
+ /// registered.
///
- /// A string representation of the digest meanism.
- /// A DerObjectIdentifier, null if the Oid is not available.
+ /// A digest name or alias (e.g. "SHA-256").
+ /// If is null.
public static DerObjectIdentifier GetObjectIdentifier(string mechanism)
{
if (mechanism == null)
diff --git a/crypto/src/security/GeneratorUtilities.cs b/crypto/src/security/GeneratorUtilities.cs
index a0606a82f..5dea4230d 100644
--- a/crypto/src/security/GeneratorUtilities.cs
+++ b/crypto/src/security/GeneratorUtilities.cs
@@ -22,6 +22,16 @@
namespace Org.BouncyCastle.Security
{
+ ///
+ /// Factory for symmetric key generators () and asymmetric key pair
+ /// generators (), resolved by algorithm name or ASN.1 OID.
+ ///
+ ///
+ /// Names are matched case-insensitively. Symmetric generators are pre-configured with the algorithm's
+ /// default key size; asymmetric generators are returned uninitialised — the caller must invoke
+ /// with appropriate
+ /// before generating a key pair.
+ ///
public static class GeneratorUtilities
{
private static readonly IDictionary KgAlgorithms =
@@ -352,11 +362,18 @@ internal static string GetCanonicalKeyPairGeneratorAlgorithm(string algorithm)
return CollectionUtilities.GetValueOrNull(KpgAlgorithms, algorithm);
}
+ /// Resolve a for the given symmetric algorithm OID.
public static CipherKeyGenerator GetKeyGenerator(DerObjectIdentifier oid)
{
return GetKeyGenerator(oid.Id);
}
+ ///
+ /// Resolve a for the named symmetric algorithm (e.g. "AES",
+ /// "DESede", "ChaCha20"), pre-configured with the algorithm's default key size.
+ ///
+ /// If the algorithm is not recognised or has no default
+ /// key size.
public static CipherKeyGenerator GetKeyGenerator(string algorithm)
{
string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm);
@@ -378,11 +395,17 @@ public static CipherKeyGenerator GetKeyGenerator(string algorithm)
return new CipherKeyGenerator(defaultKeySize);
}
+ /// Resolve an for the given algorithm OID.
public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(DerObjectIdentifier oid)
{
return GetKeyPairGenerator(oid.Id);
}
+ ///
+ /// Resolve an for the named asymmetric algorithm
+ /// (e.g. "RSA", "ECDSA", "Ed25519", "DH").
+ ///
+ /// If the algorithm is not recognised.
public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(string algorithm)
{
string canonicalName = GetCanonicalKeyPairGeneratorAlgorithm(algorithm);
diff --git a/crypto/src/security/MacUtilities.cs b/crypto/src/security/MacUtilities.cs
index 444e0fb42..6c10b41fa 100644
--- a/crypto/src/security/MacUtilities.cs
+++ b/crypto/src/security/MacUtilities.cs
@@ -17,8 +17,14 @@
namespace Org.BouncyCastle.Security
{
+ ///
+ /// Factory for instances (HMAC, CMAC, GMAC, Poly1305, etc.) and convenience helpers for
+ /// one-shot MAC computation.
+ ///
///
- /// Utility class for creating HMac object from their names/Oids
+ /// MACs can be looked up by canonical name (e.g. "HMAC-SHA256", "AESCMAC") or by ASN.1 OID;
+ /// names are matched case-insensitively. The returned is uninitialised — the caller
+ /// must invoke with a key before processing data.
///
public static class MacUtilities
{
@@ -111,6 +117,12 @@ static MacUtilities()
#endif
}
+ ///
+ /// One-shot MAC of using the named algorithm and the supplied key parameters.
+ ///
+ /// A MAC name or alias (e.g. "HMAC-SHA256").
+ /// Key (and any other) parameters required to initialise the MAC.
+ /// The data to authenticate.
public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[] input)
{
IMac mac = GetMac(algorithm);
@@ -119,6 +131,7 @@ public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[]
return DoFinal(mac);
}
+ /// Finalises and returns the resulting tag as a fresh array.
public static byte[] DoFinal(IMac mac)
{
byte[] b = new byte[mac.GetMacSize()];
@@ -126,17 +139,26 @@ public static byte[] DoFinal(IMac mac)
return b;
}
+ /// Feeds into , then finalises and returns the
+ /// tag.
public static byte[] DoFinal(IMac mac, byte[] input)
{
mac.BlockUpdate(input, 0, input.Length);
return DoFinal(mac);
}
+ ///
+ /// Returns the canonical algorithm name registered for the given ASN.1 OID, or null if the OID
+ /// is not mapped to a known MAC.
+ ///
public static string GetAlgorithmName(DerObjectIdentifier oid)
{
return CollectionUtilities.GetValueOrNull(AlgorithmOidMap, oid);
}
+ /// Resolve and instantiate an for the given ASN.1 algorithm OID.
+ /// If is null.
+ /// If the OID does not map to a known MAC.
// TODO[api] Change parameter name to 'oid'
public static IMac GetMac(DerObjectIdentifier id)
{
@@ -153,6 +175,11 @@ public static IMac GetMac(DerObjectIdentifier id)
throw new SecurityUtilityException("Mac OID not recognised.");
}
+ /// Resolve and instantiate an by name (or alias).
+ /// A MAC name (e.g. "HMAC-SHA512", "AESCMAC",
+ /// "POLY1305").
+ /// If is null.
+ /// If the MAC name is not recognised.
public static IMac GetMac(string algorithm)
{
if (algorithm == null)
diff --git a/crypto/src/security/ParameterUtilities.cs b/crypto/src/security/ParameterUtilities.cs
index 7dd76b0d1..d47e918d6 100644
--- a/crypto/src/security/ParameterUtilities.cs
+++ b/crypto/src/security/ParameterUtilities.cs
@@ -17,6 +17,17 @@
namespace Org.BouncyCastle.Security
{
+ ///
+ /// Helpers for building values: creating algorithm-appropriate
+ /// instances, decoding ASN.1 algorithm parameters into IV-bearing
+ /// , generating random IV/parameter blocks, and wrapping/unwrapping
+ /// / envelopes.
+ ///
+ ///
+ /// Algorithm names are resolved through and matched
+ /// case-insensitively. DES, DES-EDE and RC2 receive their dedicated parameter subclasses with parity
+ /// enforcement; other algorithms get a plain .
+ ///
public static class ParameterUtilities
{
private static readonly IDictionary Algorithms =
@@ -195,21 +206,30 @@ private static void AddBasicIVSizeEntries(int size, params string[] algorithms)
}
}
+ ///
+ /// Returns the canonical algorithm name for the given alias or OID string, or null if the
+ /// algorithm is not recognised.
+ ///
public static string GetCanonicalAlgorithmName(string algorithm)
{
return CollectionUtilities.GetValueOrNull(Algorithms, algorithm);
}
+ ///
+ /// Build a for the algorithm identified by .
+ ///
public static KeyParameter CreateKeyParameter(DerObjectIdentifier algOid, byte[] keyBytes)
{
return CreateKeyParameter(algOid.Id, keyBytes, 0, keyBytes.Length);
}
+ /// Build a for the named algorithm.
public static KeyParameter CreateKeyParameter(string algorithm, byte[] keyBytes)
{
return CreateKeyParameter(algorithm, keyBytes, 0, keyBytes.Length);
}
+ /// Build a from a slice of .
public static KeyParameter CreateKeyParameter(
DerObjectIdentifier algOid,
byte[] keyBytes,
@@ -219,6 +239,13 @@ public static KeyParameter CreateKeyParameter(
return CreateKeyParameter(algOid.Id, keyBytes, offset, length);
}
+ ///
+ /// Build a from a slice of . DES / DES-EDE / RC2
+ /// keys are returned as their dedicated parameter subclasses; all other algorithms get a plain
+ /// .
+ ///
+ /// If is null.
+ /// If the algorithm is not recognised.
public static KeyParameter CreateKeyParameter(
string algorithm,
byte[] keyBytes,
@@ -245,6 +272,11 @@ public static KeyParameter CreateKeyParameter(
return new KeyParameter(keyBytes, offset, length);
}
+ ///
+ /// Combine a key with ASN.1-encoded algorithm parameters, returning the appropriate
+ /// envelope (e.g. or
+ /// for AES-GCM/CCM).
+ ///
public static ICipherParameters GetCipherParameters(
DerObjectIdentifier algOid,
ICipherParameters key,
@@ -253,6 +285,13 @@ public static ICipherParameters GetCipherParameters(
return GetCipherParameters(algOid.Id, key, asn1Params);
}
+ ///
+ /// Combine a key with ASN.1-encoded algorithm parameters for the named algorithm. See the OID
+ /// overload.
+ ///
+ /// If cannot supply the data required by
+ /// an AEAD mode, or the parameters block cannot be parsed.
+ /// If the algorithm is not recognised.
public static ICipherParameters GetCipherParameters(
string algorithm,
ICipherParameters key,
@@ -330,6 +369,10 @@ public static ICipherParameters GetCipherParameters(
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
}
+ ///
+ /// Generate a fresh ASN.1-encoded algorithm parameters block (typically a random IV) for the
+ /// algorithm identified by .
+ ///
public static Asn1Encodable GenerateParameters(
DerObjectIdentifier algID,
SecureRandom random)
@@ -337,6 +380,14 @@ public static Asn1Encodable GenerateParameters(
return GenerateParameters(algID.Id, random);
}
+ ///
+ /// Generate a fresh ASN.1-encoded algorithm parameters block for the named algorithm. CAST5, IDEA and
+ /// RC2 receive their dedicated parameter structures; other IV-based algorithms get a plain
+ /// containing the IV.
+ ///
+ /// If is null.
+ /// If the algorithm is not recognised or has no
+ /// parameter generator.
public static Asn1Encodable GenerateParameters(
string algorithm,
SecureRandom random)
@@ -369,6 +420,17 @@ public static Asn1Encodable GenerateParameters(
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
}
+ ///
+ /// Unwrap a envelope, returning the inner parameters and copying the
+ /// context bytes out via . If the envelope is absent,
+ /// is set to null and the input is returned unchanged.
+ ///
+ /// Parameters to inspect.
+ /// Minimum permitted context length, inclusive.
+ /// Maximum permitted context length, inclusive.
+ /// Receives the context bytes, or null if no envelope is present.
+ /// If the context length falls outside
+ /// [, ].
public static ICipherParameters GetContext(ICipherParameters cipherParameters, int minLen, int maxLen,
out byte[] context)
{
@@ -389,6 +451,11 @@ public static ICipherParameters GetContext(ICipherParameters cipherParameters, i
return cipherParameters;
}
+ ///
+ /// Unwrap a envelope, returning the inner parameters and exposing the
+ /// attached via . If the envelope is absent,
+ /// is set to null and the input is returned unchanged.
+ ///
public static ICipherParameters GetRandom(ICipherParameters cipherParameters, out SecureRandom random)
{
if (cipherParameters is ParametersWithRandom withRandom)
@@ -401,6 +468,10 @@ public static ICipherParameters GetRandom(ICipherParameters cipherParameters, ou
return cipherParameters;
}
+ ///
+ /// Strip any envelope and return the inner parameters; otherwise return
+ /// the input unchanged.
+ ///
public static ICipherParameters IgnoreRandom(ICipherParameters cipherParameters)
{
if (cipherParameters is ParametersWithRandom withRandom)
@@ -409,6 +480,10 @@ public static ICipherParameters IgnoreRandom(ICipherParameters cipherParameters)
return cipherParameters;
}
+ ///
+ /// Wrap in a envelope when
+ /// is non-null; otherwise return unchanged.
+ ///
public static ICipherParameters WithContext(ICipherParameters cp, byte[] context)
{
if (context != null)
@@ -418,6 +493,10 @@ public static ICipherParameters WithContext(ICipherParameters cp, byte[] context
return cp;
}
+ ///
+ /// Wrap in a envelope when
+ /// is non-null; otherwise return unchanged.
+ ///
public static ICipherParameters WithRandom(ICipherParameters cp, SecureRandom random)
{
if (random != null)
diff --git a/crypto/src/security/SignerUtilities.cs b/crypto/src/security/SignerUtilities.cs
index f3bdb5c58..9af85ee74 100644
--- a/crypto/src/security/SignerUtilities.cs
+++ b/crypto/src/security/SignerUtilities.cs
@@ -26,8 +26,21 @@
namespace Org.BouncyCastle.Security
{
///
- /// Signer Utility class contains methods that can not be specifically grouped into other classes.
+ /// Factory for instances and helpers for resolving signature algorithm metadata
+ /// (X.509 algorithm parameters, OID lookup) from algorithm names or OIDs.
///
+ ///
+ ///
+ /// Algorithm names follow the JCA-style DIGESTwithCIPHER convention (for example
+ /// "SHA256withRSA", "SHA1withECDSA", "SHA256withRSAandMGF1") and a number of common
+ /// aliases are recognised; matching is case-insensitive.
+ ///
+ ///
+ /// The returned is uninitialised — the caller must invoke
+ /// before processing data, or use the higher-level
+ /// overloads.
+ ///
+ ///
public static class SignerUtilities
{
private static readonly Dictionary AlgorithmMap =
@@ -613,8 +626,14 @@ private static void AddAlgorithm(string name, DerObjectIdentifier oid, bool isNo
}
}
+ /// The set of canonical signature algorithm names recognised by this factory.
public static ICollection Algorithms => CollectionUtilities.ReadOnly(Oids.Keys);
+ ///
+ /// Returns the default X.509 AlgorithmIdentifier parameters block for the given signature
+ /// algorithm OID. For RSASSA-PSS variants this constructs a populated RSASSA-PSS-params
+ /// structure; for most other algorithms is returned.
+ ///
// TODO[api] Change parameter name to 'oid'
public static Asn1Encodable GetDefaultX509Parameters(DerObjectIdentifier id)
{
@@ -627,6 +646,10 @@ public static Asn1Encodable GetDefaultX509Parameters(DerObjectIdentifier id)
return GetDefaultX509ParametersForMechanism(mechanism);
}
+ ///
+ /// Returns the default X.509 AlgorithmIdentifier parameters block for the named signature
+ /// algorithm. See the OID overload for behaviour.
+ ///
public static Asn1Encodable GetDefaultX509Parameters(string algorithm)
{
if (algorithm == null)
@@ -655,6 +678,10 @@ private static Asn1Encodable GetDefaultX509ParametersForMechanism(string mechani
return DerNull.Instance;
}
+ ///
+ /// Returns the canonical signature algorithm name registered for the given ASN.1 OID, or null
+ /// if the OID is not mapped.
+ ///
public static string GetEncodingName(DerObjectIdentifier oid)
{
return CollectionUtilities.GetValueOrNull(AlgorithmOidMap, oid);
@@ -704,6 +731,11 @@ private static Asn1Encodable GetPssX509Parameters(
DerInteger.ValueOf(saltLen), RsassaPssParameters.DefaultTrailerField);
}
+ ///
+ /// Resolve and instantiate an for the given ASN.1 algorithm OID.
+ ///
+ /// If is null.
+ /// If the OID does not map to a known signer.
// TODO[api] Change parameter name to 'oid'
public static ISigner GetSigner(DerObjectIdentifier id)
{
@@ -720,6 +752,12 @@ public static ISigner GetSigner(DerObjectIdentifier id)
throw new SecurityUtilityException("Signer OID not recognised.");
}
+ ///
+ /// Resolve and instantiate an by name (e.g. "SHA256withRSA",
+ /// "SHA1withECDSA", "Ed25519").
+ ///
+ /// If is null.
+ /// If the algorithm name is not recognised.
public static ISigner GetSigner(string algorithm)
{
if (algorithm == null)
@@ -903,6 +941,17 @@ private static ISigner GetSignerForMechanism(string mechanism)
return null;
}
+ ///
+ /// Resolve a signer for the given OID and initialise it for signing or verification.
+ ///
+ /// The signature algorithm OID.
+ /// true to initialise for signing (private key required);
+ /// false for verification (public key).
+ /// The signing or verification key.
+ /// Source of randomness, used by signers that require it; ignored
+ /// otherwise.
+ /// If is null.
+ /// If the OID is not recognised.
// TODO[api] Rename 'privateKey' to 'key'
public static ISigner InitSigner(DerObjectIdentifier algorithmOid, bool forSigning,
AsymmetricKeyParameter privateKey, SecureRandom random)
@@ -916,6 +965,10 @@ public static ISigner InitSigner(DerObjectIdentifier algorithmOid, bool forSigni
return InitSignerForMechanism(mechanism, forSigning, privateKey, random);
}
+ ///
+ /// Resolve a signer by name and initialise it for signing or verification. See the OID overload for
+ /// parameter semantics.
+ ///
// TODO[api] Rename 'privateKey' to 'key'
public static ISigner InitSigner(string algorithm, bool forSigning, AsymmetricKeyParameter privateKey,
SecureRandom random)