1104 lines
32 KiB
C++
1104 lines
32 KiB
C++
// ____ ______ __
|
|
// / __ \ / ____// /
|
|
// / /_/ // / / /
|
|
// / ____// /___ / /___ PixInsight Class Library
|
|
// /_/ \____//_____/ PCL 2.4.23
|
|
// ----------------------------------------------------------------------------
|
|
// pcl/Cryptography.h - Released 2022-03-12T18:59:29Z
|
|
// ----------------------------------------------------------------------------
|
|
// This file is part of the PixInsight Class Library (PCL).
|
|
// PCL is a multiplatform C++ framework for development of PixInsight modules.
|
|
//
|
|
// Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved.
|
|
//
|
|
// Redistribution and use in both source and binary forms, with or without
|
|
// modification, is permitted provided that the following conditions are met:
|
|
//
|
|
// 1. All redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. All redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
|
|
// of their contributors, may be used to endorse or promote products derived
|
|
// from this software without specific prior written permission. For written
|
|
// permission, please contact info@pixinsight.com.
|
|
//
|
|
// 4. All products derived from this software, in any form whatsoever, must
|
|
// reproduce the following acknowledgment in the end-user documentation
|
|
// and/or other materials provided with the product:
|
|
//
|
|
// "This product is based on software from the PixInsight project, developed
|
|
// by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
|
|
//
|
|
// Alternatively, if that is where third-party acknowledgments normally
|
|
// appear, this acknowledgment must be reproduced in the product itself.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
|
|
// INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
|
|
// DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#ifndef __PCL_Cryptography_h
|
|
#define __PCL_Cryptography_h
|
|
|
|
/// \file pcl/Cryptography.h
|
|
|
|
#include <pcl/Defs.h>
|
|
#include <pcl/Diagnostics.h>
|
|
|
|
#include <pcl/AutoPointer.h>
|
|
#include <pcl/ByteArray.h>
|
|
#include <pcl/Exception.h>
|
|
#include <pcl/String.h>
|
|
|
|
namespace pcl
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \defgroup cryptography_classes Cryptographic Hashing and Encryption Classes
|
|
*/
|
|
|
|
/*!
|
|
* \class CryptographicHash
|
|
* \brief Abstract base class for cryptographic hashing algorithm
|
|
* implementations
|
|
*
|
|
* %CryptographicHash defines a common interface for implementations of
|
|
* cryptographic hashing algorithms such as MD-5, SHA-1 or SHA-256.
|
|
*
|
|
* \ingroup cryptography_classes
|
|
* \sa MD5, SHA1, SHA224, SHA256, SHA384, SHA512, CryptographicHashFactory
|
|
*/
|
|
class PCL_CLASS CryptographicHash
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Default constructor.
|
|
*/
|
|
CryptographicHash() = default;
|
|
|
|
/*!
|
|
* Destroys a %CryptographicHash object.
|
|
*/
|
|
virtual ~CryptographicHash()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor. This constructor is disabled because %CryptographicHash
|
|
* objects are unique.
|
|
*/
|
|
CryptographicHash( const CryptographicHash& ) = delete;
|
|
|
|
/*!
|
|
* Copy assignment. This operator is disabled because %CryptographicHash
|
|
* objects are unique.
|
|
*/
|
|
CryptographicHash& operator =( const CryptographicHash& ) = delete;
|
|
|
|
/*!
|
|
* Returns the name of this cryptographic hashing algorithm.
|
|
*/
|
|
virtual String AlgorithmName() const = 0;
|
|
|
|
/*!
|
|
* Returns the length in bytes of a hash sequence (or message digest)
|
|
* calculated with this cryptographic hashing algorithm.
|
|
*/
|
|
virtual size_type HashLength() const = 0;
|
|
|
|
/*!
|
|
* Initializes this cryptographic hash generator.
|
|
*/
|
|
virtual void Initialize() = 0;
|
|
|
|
/*!
|
|
* Updates the hash generator with a new \a data chunk of the specified
|
|
* \a length in bytes.
|
|
*/
|
|
virtual void Update( const void* data, size_type length ) = 0;
|
|
|
|
/*!
|
|
* Updates the hash generator with data from a container with contiguous
|
|
* storage.
|
|
*
|
|
* The \c C template argument must be a class with PCL container semantics
|
|
* (the Begin() and Size() member functions are required). Typically the
|
|
* ByteArray class is used, although any array-like class with contiguous
|
|
* storage is appropriate, including Array, String, Vector and Matrix.
|
|
*/
|
|
template <class C>
|
|
void Update( const C& data )
|
|
{
|
|
Update( data.Begin(), data.Size() );
|
|
}
|
|
|
|
/*!
|
|
* Terminates hash generation and returns the computed message digest
|
|
* as a ByteArray instance.
|
|
*/
|
|
ByteArray Finalize()
|
|
{
|
|
ByteArray hash( HashLength() );
|
|
Finalize( hash.Begin() );
|
|
return hash;
|
|
}
|
|
|
|
/*!
|
|
* Returns the hash sequence (message digest) corresponding to a \a data
|
|
* block of the specified \a length in bytes, stored in the specified
|
|
* \a hash array. The specified array must provide room for at least
|
|
* HashLength() bytes, that is, the length in bytes of the message digest
|
|
* produced by this hashing algorithm.
|
|
*/
|
|
void Hash( uint8* hash, const void* data, size_type length )
|
|
{
|
|
Initialize();
|
|
Update( data, length );
|
|
Finalize( hash );
|
|
}
|
|
|
|
/*!
|
|
* Returns the hash sequence (message digest) corresponding to a \a data
|
|
* block of the specified \a length in bytes, as a ByteArray instance.
|
|
*/
|
|
ByteArray Hash( const void* data, size_type length )
|
|
{
|
|
ByteArray hash( HashLength() );
|
|
Hash( hash.Begin(), data, length );
|
|
return hash;
|
|
}
|
|
|
|
/*!
|
|
* Returns the hash sequence (message digest) corresponding to a container
|
|
* \a data with contiguous storage as a ByteArray instance.
|
|
*
|
|
* The \c C template argument must be a class with PCL container semantics
|
|
* (the Begin() and Size() member functions are required). Typically the
|
|
* ByteArray class is used, although any array-like class with contiguous
|
|
* storage is appropriate, including Array, String, Vector and Matrix.
|
|
*/
|
|
template <class C>
|
|
ByteArray Hash( const C& data )
|
|
{
|
|
return Hash( data.Begin(), data.Size() );
|
|
}
|
|
|
|
protected:
|
|
|
|
/*!
|
|
* Terminates hash generation and returns the computed message digest
|
|
* (hash value) stored in the specified \a hash array. The specified array
|
|
* must provide room for at least HashLength() bytes, that is, the length in
|
|
* bytes of the message digest produced by this hashing algorithm.
|
|
*/
|
|
virtual void Finalize( void* hash ) = 0;
|
|
|
|
friend class CryptographicHashFactory;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class MD5
|
|
* \brief Implementation of the %MD5 cryptographic hashing algorithm
|
|
*
|
|
* \b References
|
|
*
|
|
* Message Digest algorithm 5 (%MD5) was designed by Ronald Rivest in 1991.
|
|
* %MD5 is a widely-used Internet standard published as RFC-1321 by RSA:
|
|
*
|
|
* http://tools.ietf.org/html/rfc1321
|
|
*
|
|
* An %MD5 message digest (or %MD5 hash value) is 128 bits (16 bytes) long.
|
|
*
|
|
* \ingroup cryptography_classes
|
|
* \sa CryptographicHash, SHA1, SHA224, SHA256, SHA384, SHA512,
|
|
* CryptographicHashFactory
|
|
*/
|
|
class PCL_CLASS MD5 : public CryptographicHash
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs an %MD5 hash generator.
|
|
*/
|
|
MD5() = default;
|
|
|
|
/*!
|
|
* Destroys an %MD5 hash generator.
|
|
*/
|
|
virtual ~MD5();
|
|
|
|
/*!
|
|
* Returns the name of this cryptographic hashing algorithm: "MD5".
|
|
*/
|
|
String AlgorithmName() const override
|
|
{
|
|
return "MD5";
|
|
}
|
|
|
|
/*!
|
|
* Returns the length in bytes of a hash sequence (or message digest)
|
|
* calculated with this cryptographic hashing algorithm.
|
|
*
|
|
* As reimplemented in %MD5, this function returns 16, the length in bytes
|
|
* of an %MD5 digest.
|
|
*/
|
|
size_type HashLength() const override
|
|
{
|
|
return 16;
|
|
}
|
|
|
|
/*!
|
|
*/
|
|
void Initialize() override;
|
|
|
|
/*!
|
|
*/
|
|
void Update( const void* data, size_type length ) override;
|
|
|
|
private:
|
|
|
|
void* m_context = nullptr;
|
|
|
|
/*!
|
|
*/
|
|
void Finalize( void* hash ) override;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class SHA1
|
|
* \brief Implementation of the SHA-1 cryptographic hashing algorithm
|
|
*
|
|
* \b References
|
|
*
|
|
* The initial Secure Hash Algorithm (SHA) was published by NIST in 1993 as the
|
|
* Secure Hash Standard, FIPS PUB 180. The SHA-1 algorithm was defined in a
|
|
* revised version published in 1995, FIPS PUB 180-1. The latest specification
|
|
* has been released in FIPS PUB 180-4:
|
|
*
|
|
* http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
|
*
|
|
* An SHA-1 message digest (or SHA-1 hash value) is 160 bits (20 bytes) long.
|
|
*
|
|
* \ingroup cryptography_classes
|
|
* \sa CryptographicHash, MD5, SHA224, SHA256, SHA384, SHA512,
|
|
* CryptographicHashFactory
|
|
*/
|
|
class PCL_CLASS SHA1 : public CryptographicHash
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs an SHA-1 hash generator.
|
|
*/
|
|
SHA1() = default;
|
|
|
|
/*!
|
|
* Destroys an SHA-1 hash generator.
|
|
*/
|
|
virtual ~SHA1();
|
|
|
|
/*!
|
|
* Returns the name of this cryptographic hashing algorithm: "SHA1".
|
|
*/
|
|
String AlgorithmName() const override
|
|
{
|
|
return "SHA1";
|
|
}
|
|
|
|
/*!
|
|
* Returns the length in bytes of a hash sequence (or message digest)
|
|
* calculated with this cryptographic hashing algorithm.
|
|
*
|
|
* As reimplemented in %SHA1, this function returns 20, the length in bytes
|
|
* of an SHA-1 digest.
|
|
*/
|
|
size_type HashLength() const override
|
|
{
|
|
return 20;
|
|
}
|
|
|
|
/*!
|
|
*/
|
|
void Initialize() override;
|
|
|
|
/*!
|
|
*/
|
|
void Update( const void* data, size_type length ) override;
|
|
|
|
private:
|
|
|
|
void* m_context = nullptr; // RFC4634
|
|
|
|
/*!
|
|
*/
|
|
void Finalize( void* hash ) override;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class SHA224
|
|
* \brief Implementation of the SHA-224 cryptographic hashing algorithm
|
|
*
|
|
* \b References
|
|
*
|
|
* The SHA-2 family of secure hash functions (SHA-256, SHA-384, and SHA-512)
|
|
* was specified by NIST in 2002 with the publication of FIPS PUB 180-2. The
|
|
* SHA-224 variant was released in a change notice for FIPS PUB 180-2 in 2004.
|
|
* FIPS PUB 180-2 has been superseded by FIPS PUB 180-3 and FIPS PUB 180-4:
|
|
*
|
|
* http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
|
*
|
|
* An SHA-224 message digest is 224 bits (28 bytes) long.
|
|
*
|
|
* \ingroup cryptography_classes
|
|
* \sa CryptographicHash, MD5, SHA1, SHA256, SHA384, SHA512,
|
|
* CryptographicHashFactory
|
|
*/
|
|
class PCL_CLASS SHA224 : public CryptographicHash
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs an SHA-224 hash generator.
|
|
*/
|
|
SHA224() = default;
|
|
|
|
/*!
|
|
* Destroys an SHA-224 hash generator.
|
|
*/
|
|
virtual ~SHA224();
|
|
|
|
/*!
|
|
* Returns the name of this cryptographic hashing algorithm: "SHA224".
|
|
*/
|
|
String AlgorithmName() const override
|
|
{
|
|
return "SHA224";
|
|
}
|
|
|
|
/*!
|
|
* Returns the length in bytes of a hash sequence (or message digest)
|
|
* calculated with this cryptographic hashing algorithm.
|
|
*
|
|
* As reimplemented in %SHA224, this function returns 28, the length in
|
|
* bytes of an SHA-224 digest.
|
|
*/
|
|
size_type HashLength() const override
|
|
{
|
|
return 28;
|
|
}
|
|
|
|
/*!
|
|
*/
|
|
void Initialize() override;
|
|
|
|
/*!
|
|
*/
|
|
void Update( const void* data, size_type length ) override;
|
|
|
|
private:
|
|
|
|
void* m_context = nullptr; // RFC4634
|
|
|
|
/*!
|
|
*/
|
|
void Finalize( void* hash ) override;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class SHA256
|
|
* \brief Implementation of the SHA-256 cryptographic hashing algorithm
|
|
*
|
|
* \b References
|
|
*
|
|
* The SHA-2 family of secure hash functions (SHA-256, SHA-384, and SHA-512)
|
|
* was specified by NIST in 2002 with the publication of FIPS PUB 180-2. FIPS
|
|
* PUB 180-2 has been superseded by FIPS PUB 180-3 and FIPS PUB 180-4:
|
|
*
|
|
* http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
|
*
|
|
* An SHA-256 message digest is 256 bits (32 bytes) long.
|
|
*
|
|
* \ingroup cryptography_classes
|
|
* \sa CryptographicHash, MD5, SHA1, SHA224, SHA384, SHA512,
|
|
* CryptographicHashFactory
|
|
*/
|
|
class PCL_CLASS SHA256 : public CryptographicHash
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs an SHA-256 hash generator.
|
|
*/
|
|
SHA256() = default;
|
|
|
|
/*!
|
|
* Destroys an SHA-256 hash generator.
|
|
*/
|
|
virtual ~SHA256();
|
|
|
|
/*!
|
|
* Returns the name of this cryptographic hashing algorithm: "SHA256".
|
|
*/
|
|
String AlgorithmName() const override
|
|
{
|
|
return "SHA256";
|
|
}
|
|
|
|
/*!
|
|
* Returns the length in bytes of a hash sequence (or message digest)
|
|
* calculated with this cryptographic hashing algorithm.
|
|
*
|
|
* As reimplemented in %SHA256, this function returns 32, the length in
|
|
* bytes of an SHA-256 digest.
|
|
*/
|
|
size_type HashLength() const override
|
|
{
|
|
return 32;
|
|
}
|
|
|
|
/*!
|
|
*/
|
|
void Initialize() override;
|
|
|
|
/*!
|
|
*/
|
|
void Update( const void* data, size_type length ) override;
|
|
|
|
private:
|
|
|
|
void* m_context = nullptr; // RFC4634
|
|
|
|
/*!
|
|
*/
|
|
void Finalize( void* hash ) override;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class SHA384
|
|
* \brief Implementation of the SHA-384 cryptographic hashing algorithm
|
|
*
|
|
* \b References
|
|
*
|
|
* The SHA-2 family of secure hash functions (SHA-384, SHA-384, and SHA-512)
|
|
* was specified by NIST in 2002 with the publication of FIPS PUB 180-2. FIPS
|
|
* PUB 180-2 has been superseded by FIPS PUB 180-3 and FIPS PUB 180-4:
|
|
*
|
|
* http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
|
*
|
|
* An SHA-384 message digest is 384 bits (48 bytes) long.
|
|
*
|
|
* \ingroup cryptography_classes
|
|
* \sa CryptographicHash, MD5, SHA1, SHA224, SHA256, SHA512,
|
|
* CryptographicHashFactory
|
|
*/
|
|
class PCL_CLASS SHA384 : public CryptographicHash
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs an SHA-384 hash generator.
|
|
*/
|
|
SHA384() = default;
|
|
|
|
/*!
|
|
* Destroys an SHA-384 hash generator.
|
|
*/
|
|
virtual ~SHA384();
|
|
|
|
/*!
|
|
* Returns the name of this cryptographic hashing algorithm: "SHA384".
|
|
*/
|
|
String AlgorithmName() const override
|
|
{
|
|
return "SHA384";
|
|
}
|
|
|
|
/*!
|
|
* Returns the length in bytes of a hash sequence (or message digest)
|
|
* calculated with this cryptographic hashing algorithm.
|
|
*
|
|
* As reimplemented in %SHA384, this function returns 48, the length in
|
|
* bytes of an SHA-384 digest.
|
|
*/
|
|
size_type HashLength() const override
|
|
{
|
|
return 48;
|
|
}
|
|
|
|
/*!
|
|
*/
|
|
void Initialize() override;
|
|
|
|
/*!
|
|
*/
|
|
void Update( const void* data, size_type length ) override;
|
|
|
|
private:
|
|
|
|
void* m_context = nullptr; // RFC4634
|
|
|
|
/*!
|
|
*/
|
|
void Finalize( void* hash ) override;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class SHA512
|
|
* \brief Implementation of the SHA-512 cryptographic hashing algorithm
|
|
*
|
|
* \b References
|
|
*
|
|
* The SHA-2 family of secure hash functions (SHA-384, SHA-384, and SHA-512)
|
|
* was specified by NIST in 2002 with the publication of FIPS PUB 180-2. FIPS
|
|
* PUB 180-2 has been superseded by FIPS PUB 180-3 and FIPS PUB 180-4:
|
|
*
|
|
* http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
|
*
|
|
* An SHA-512 message digest is 512 bits (64 bytes) long.
|
|
*
|
|
* \ingroup cryptography_classes
|
|
* \sa CryptographicHash, MD5, SHA1, SHA224, SHA256, SHA384,
|
|
* CryptographicHashFactory
|
|
*/
|
|
class PCL_CLASS SHA512 : public CryptographicHash
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs an SHA-512 hash generator.
|
|
*/
|
|
SHA512() = default;
|
|
|
|
/*!
|
|
* Destroys an SHA-512 hash generator.
|
|
*/
|
|
virtual ~SHA512();
|
|
|
|
/*!
|
|
* Returns the name of this cryptographic hashing algorithm: "SHA512".
|
|
*/
|
|
String AlgorithmName() const override
|
|
{
|
|
return "SHA512";
|
|
}
|
|
|
|
/*!
|
|
* Returns the length in bytes of a hash sequence (or message digest)
|
|
* calculated with this cryptographic hashing algorithm.
|
|
*
|
|
* As reimplemented in %SHA512, this function returns 64, the length in
|
|
* bytes of an SHA-512 digest.
|
|
*/
|
|
size_type HashLength() const override
|
|
{
|
|
return 64;
|
|
}
|
|
|
|
/*!
|
|
*/
|
|
void Initialize() override;
|
|
|
|
/*!
|
|
*/
|
|
void Update( const void* data, size_type length ) override;
|
|
|
|
private:
|
|
|
|
void* m_context = nullptr; // RFC4634
|
|
|
|
/*!
|
|
*/
|
|
void Finalize( void* hash ) override;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class CryptographicHashFactory
|
|
* \brief Selectable cryptographic hashing algorithm
|
|
*
|
|
* %CryptographicHashFactory implements a cryptographic hashing algorithm that
|
|
* can be selected upon construction among all of the algorithms implemented in
|
|
* the PixInsight/PCL platform. This currently includes MD-5, SHA-1, SHA-224,
|
|
* SHA-256, SHA-384, and SHA-512.
|
|
*
|
|
* \ingroup cryptography_classes
|
|
* \sa CryptographicHash, MD5, SHA1, SHA224, SHA256, SHA384, SHA512
|
|
*/
|
|
class PCL_CLASS CryptographicHashFactory : public CryptographicHash
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Constructs a %CryptographicHashFactory object to implement the specified
|
|
* hashing algorithm.
|
|
*
|
|
* \param algorithmName Name of a supported cryptographic hashing algorithm.
|
|
* Currently this parameter can be one of: "md5",
|
|
* "sha1", "sha224", "sha256", "sha384", and "sha512".
|
|
* Comparisons are performed on trimmed strings and
|
|
* case-insensitive.
|
|
*
|
|
* If an invalid or unsupported algorithm name is specified, this
|
|
* constructor throws an Error exception.
|
|
*/
|
|
CryptographicHashFactory( const IsoString& algorithmName )
|
|
{
|
|
switch ( algorithmName.Trimmed().CaseFolded().Hash32() )
|
|
{
|
|
case 0x445dd715: m_hash = new MD5; break;
|
|
case 0x3cac24af: m_hash = new SHA1; break;
|
|
case 0x7e50b015: m_hash = new SHA224; break;
|
|
case 0xcbbce793: m_hash = new SHA256; break;
|
|
case 0x858a0d3d: m_hash = new SHA384; break;
|
|
case 0xb24dfd53: m_hash = new SHA512; break;
|
|
default:
|
|
throw Error( "CryptographicHashFactory: Unknown/unsupported algorithm \'" + algorithmName + '\'' );
|
|
}
|
|
}
|
|
|
|
CryptographicHashFactory( const IsoString::ustring_base& algorithmName )
|
|
: CryptographicHashFactory( IsoString( algorithmName ) )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Destroys a %CryptographicHashFactory object.
|
|
*/
|
|
virtual ~CryptographicHashFactory()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Returns the name of this cryptographic hashing algorithm.
|
|
*/
|
|
String AlgorithmName() const override
|
|
{
|
|
return m_hash->AlgorithmName();
|
|
}
|
|
|
|
/*!
|
|
* Returns the length in bytes of a hash sequence (or message digest)
|
|
* calculated with this cryptographic hashing algorithm.
|
|
*/
|
|
size_type HashLength() const override
|
|
{
|
|
return m_hash->HashLength();
|
|
}
|
|
|
|
/*!
|
|
* Initializes this cryptographic hash generator.
|
|
*/
|
|
void Initialize() override
|
|
{
|
|
m_hash->Initialize();
|
|
}
|
|
|
|
/*!
|
|
* Updates the hash generator with a new \a data chunk of the specified
|
|
* \a length in bytes.
|
|
*/
|
|
void Update( const void* data, size_type length ) override
|
|
{
|
|
m_hash->Update( data, length );
|
|
}
|
|
|
|
private:
|
|
|
|
AutoPointer<CryptographicHash> m_hash;
|
|
|
|
void Finalize( void* hash ) override
|
|
{
|
|
m_hash->Finalize( hash );
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class Cipher
|
|
* \brief Abstract base class for cipher algorithm implementations
|
|
*
|
|
* %Cipher defines a common interface for implementations of algorithms
|
|
* performing encryption and decryption of generic data.
|
|
*
|
|
* Currently we have implemented the AES-256 cipher with CBC/ECB encryption and
|
|
* decryption on the PixInsight platform, available as the AES256 class.
|
|
*
|
|
* \ingroup cryptography_classes
|
|
* \sa AES256
|
|
*/
|
|
class PCL_CLASS Cipher
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Default constructor.
|
|
*/
|
|
Cipher() = default;
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
Cipher( const Cipher& ) = default;
|
|
|
|
/*!
|
|
* Copy assignment operator. Returns a reference to this object.
|
|
*/
|
|
Cipher& operator =( const Cipher& ) = default;
|
|
|
|
/*!
|
|
* Destroys a %Cipher object.
|
|
*/
|
|
virtual ~Cipher()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Returns the name of this cipher algorithm.
|
|
*/
|
|
virtual String AlgorithmName() const = 0;
|
|
|
|
/*!
|
|
* Returns the length in bytes of a key in this cipher algorithm.
|
|
*/
|
|
virtual size_type KeyLength() const = 0;
|
|
|
|
/*!
|
|
* Buffer encryption.
|
|
*
|
|
* \param[out] output Starting address of the output buffer, where the
|
|
* encrypted data (or <em>cipher text</em>) will be stored.
|
|
*
|
|
* \param input Starting address of the input buffer, where the original
|
|
* data (or <em>plain text</em>) is stored.
|
|
*
|
|
* \param length The buffer length in bytes.
|
|
*/
|
|
virtual void Encrypt( void* output, const void* input, size_type length ) const = 0;
|
|
|
|
/*!
|
|
* Buffer decryption.
|
|
*
|
|
* \param[out] output Starting address of the output buffer, where the
|
|
* decrypted data (or <em>plain text</em>) will be stored.
|
|
*
|
|
* \param input Starting address of the input buffer, where the encrypted
|
|
* data (or <em>cipher text</em>) is stored.
|
|
*
|
|
* \param length The buffer length in bytes.
|
|
*/
|
|
virtual void Decrypt( void* output, const void* input, size_type length ) const = 0;
|
|
|
|
/*!
|
|
* Container encryption.
|
|
*
|
|
* \param[out] output Starting address of the output buffer, where the
|
|
* encrypted data (or <em>cipher text</em>) will be stored.
|
|
*
|
|
* \param input Reference to a container where the original data (or
|
|
* <em>plain text</em>) is stored as a contiguous block. The
|
|
* input container will be treated as a contiguous sequence
|
|
* of bytes, ignoring the data type of the items contained.
|
|
*
|
|
* The \c C template argument must be a class with PCL container semantics
|
|
* (the Begin() and Size() member functions are required). Typically the
|
|
* ByteArray class is used, although any array-like class with contiguous
|
|
* storage is appropriate, including Array, String, Vector and Matrix.
|
|
*/
|
|
template <class C>
|
|
void Encrypt( void* output, const C& input ) const
|
|
{
|
|
Encrypt( output, input.Begin(), input.Size() );
|
|
}
|
|
|
|
/*!
|
|
* Out-of-place container encryption.
|
|
*
|
|
* \param input Reference to a container where the original data (or
|
|
* <em>plain text</em>) is stored as a contiguous block. The
|
|
* input container will be treated as a contiguous sequence
|
|
* of bytes, ignoring the data type of the items contained.
|
|
*
|
|
* The \c C template argument must be a class with PCL container semantics
|
|
* (the Begin() and Size() member functions are required). Typically the
|
|
* ByteArray class is used, although any array-like class with contiguous
|
|
* storage is appropriate, including Array, String, Vector and Matrix.
|
|
*
|
|
* Returns a ByteArray object with the encrypted data, or <em>cipher
|
|
* text</em>. The returned object can be used to decrypt the data with the
|
|
* Decrypt() member function.
|
|
*/
|
|
template <class C>
|
|
ByteArray Encrypt( const C& input ) const
|
|
{
|
|
ByteArray output( input.Size() );
|
|
Encrypt( output.Begin(), input.Begin(), input.Size() );
|
|
return output;
|
|
}
|
|
|
|
/*!
|
|
* Container decryption.
|
|
*
|
|
* \param[out] output Starting address of the output buffer, where the
|
|
* decrypted data (or <em>plain text</em>) will be stored.
|
|
*
|
|
* \param input Reference to a container where the encrypted data (or
|
|
* <em>cipher text</em>) is stored as a contiguous block. The
|
|
* input container will be treated as a contiguous sequence
|
|
* of bytes, ignoring the data type of the items contained.
|
|
*
|
|
* The \c C template argument must be a class with PCL container semantics
|
|
* (the Begin() and Size() member functions are required). Typically the
|
|
* ByteArray class is used, although any array-like class with contiguous
|
|
* storage is appropriate, including Array, String, Vector and Matrix.
|
|
*/
|
|
template <class C>
|
|
void Decrypt( void* output, const C& input ) const
|
|
{
|
|
Decrypt( output, input.Begin(), input.Size() );
|
|
}
|
|
|
|
/*!
|
|
* Out-of-place container decryption.
|
|
*
|
|
* \param input Reference to a container where the encrypted data (or
|
|
* <em>cipher text</em>) is stored as a contiguous block. The
|
|
* input container will be treated as a contiguous sequence
|
|
* of bytes, ignoring the data type of the items contained.
|
|
*
|
|
* The \c C template argument must be a class with PCL container semantics
|
|
* (the Begin() and Size() member functions are required). Typically the
|
|
* ByteArray class is used, although any array-like class with contiguous
|
|
* storage is appropriate, including Array, String, Vector and Matrix.
|
|
*
|
|
* Returns a ByteArray object with the decrypted data, or <em>plain
|
|
* text</em>), as a contiguous sequence of bytes.
|
|
*/
|
|
template <class C>
|
|
ByteArray Decrypt( const C& input ) const
|
|
{
|
|
ByteArray output( input.Size() );
|
|
Decrypt( output.Begin(), input.Begin(), input.Size() );
|
|
return output;
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class AES256
|
|
* \brief AES-256 cipher
|
|
*
|
|
* The %AES256 class is a FIPS-197 compliant implementation of the Advanced
|
|
* Encryption Standard (AES) cipher using 256-bit keys.
|
|
*
|
|
* \b References
|
|
*
|
|
* The AES (Advanced Encryption Standard) block cipher algorithm (originally
|
|
* called \e Rijndael) was designed by Vincent Rijmen and Joan Daemen:
|
|
*
|
|
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
|
|
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
|
*
|
|
* \ingroup cryptography_classes
|
|
*/
|
|
class PCL_CLASS AES256 : public Cipher
|
|
{
|
|
public:
|
|
|
|
enum { key_length = 32, block_length = 16 };
|
|
|
|
/*!
|
|
* Represents a 256-bit cipher key for the AES-256 algorithm.
|
|
*/
|
|
typedef uint8 key_type[ key_length ];
|
|
|
|
/*!
|
|
* Represents a 16-byte ECB encryption/decription block for the AES-256
|
|
* algorithm.
|
|
*/
|
|
typedef uint8 block_type[ block_length ];
|
|
|
|
/*!
|
|
* Constructs an AES-256 cipher object.
|
|
*
|
|
* \param key Starting address of a contiguous block of 32 bytes, which
|
|
* will be treated as the 256-bit cipher key. The first 32
|
|
* bytes stored at this address will be wiped out (replaced
|
|
* with zeros) by this constructor.
|
|
*
|
|
* \note For enhanced security, this constructor wipes out the specified
|
|
* cipher \a key, filling it with 32 zero bytes. If you want to preserve the
|
|
* key (which in general is a <em>bad idea</em> for security reasons), make
|
|
* a safe copy before invoking this constructor.
|
|
*/
|
|
AES256( void* key )
|
|
{
|
|
SetKey( key );
|
|
}
|
|
|
|
/*!
|
|
* Constructs an AES-256 cipher object.
|
|
*
|
|
* \param key 256-bit cipher key specified as an 8-bit string. The
|
|
* contents of this string Will be wiped out (filled with
|
|
* null characters) by this constructor.
|
|
*
|
|
* The AES-256 cipher key will be initialized with the lowercase hexadecimal
|
|
* representation of 20 successive MD5 checksum operations applied to the
|
|
* specified \a key string (note that an %MD5 checksum is a sequence of 16
|
|
* bytes, whose hexadecimal representation has 32 characters, or 256 bits).
|
|
*
|
|
* \note For enhanced security, this constructor wipes out the specified
|
|
* cipher \a key string, filling it with null characters. If you want to
|
|
* preserve the original key (which in general is a <em>bad idea</em> for
|
|
* security reasons), make a copy and ensure it references its string data
|
|
* uniquely before invoking this constructor.
|
|
*/
|
|
AES256( IsoString& key )
|
|
{
|
|
ByteArray h = MD5().Hash( key );
|
|
key.SecureFill();
|
|
for ( int i = 1; i < 20; ++i )
|
|
h = MD5().Hash( h );
|
|
IsoString k = IsoString::ToHex( h );
|
|
h.Fill( uint8( 0 ) );
|
|
SetKey( k.Begin() );
|
|
}
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
AES256( const AES256& ) = default;
|
|
|
|
/*!
|
|
* Copy assignment operator. Returns a reference to this object.
|
|
*/
|
|
AES256& operator =( const AES256& ) = default;
|
|
|
|
/*!
|
|
* Destroys an AES-256 cipher object.
|
|
*/
|
|
virtual ~AES256()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Returns "AES256", the name of this cipher algorithm.
|
|
*/
|
|
String AlgorithmName() const override
|
|
{
|
|
return "AES256";
|
|
}
|
|
|
|
/*!
|
|
* Returns 32, the length in bytes of a key in the AES-256 cipher algorithm.
|
|
*/
|
|
size_type KeyLength() const override
|
|
{
|
|
return 32;
|
|
}
|
|
|
|
/*!
|
|
* AES-256 buffer encryption (CBC mode).
|
|
*
|
|
* \param[out] output Starting address of the output buffer, where the
|
|
* encrypted data (or <em>cipher text</em>) will be stored.
|
|
*
|
|
* \param input Starting address of the input buffer, where the original
|
|
* data (or <em>plain text</em>) is stored.
|
|
*
|
|
* \param length The buffer length in bytes. Must be an integer multiple of
|
|
* 16 bytes.
|
|
*
|
|
* If the specified \a length is not an integer multiple of 16 bytes, this
|
|
* function throws an Error exception. If necessary, the source data must
|
|
* be padded with zeros or spaces, as required to achieve a valid length.
|
|
*/
|
|
void Encrypt( void* output, const void* input, size_type length ) const override;
|
|
|
|
/*!
|
|
* AES buffer decryption (CBC mode).
|
|
*
|
|
* \param[out] output Starting address of the output buffer, where the
|
|
* decrypted data (or <em>plain text</em>) will be stored.
|
|
*
|
|
* \param input Starting address of the input buffer, where the encrypted
|
|
* data (or <em>cipher text</em>) is stored.
|
|
*
|
|
* \param length The buffer length in bytes. Must be an integer multiple of
|
|
* 16 bytes.
|
|
*
|
|
* If the specified \a length is not an integer multiple of 16 bytes, this
|
|
* function throws an Error exception.
|
|
*/
|
|
void Decrypt( void* output, const void* input, size_type length ) const override;
|
|
|
|
/*!
|
|
* AES block encryption (ECB mode).
|
|
*
|
|
* \param[out] output Starting address of the encrypted 16-byte block.
|
|
*
|
|
* \param input Starting address of the input 16-byte block.
|
|
*/
|
|
void EncryptBlock( void* output, const void* input ) const;
|
|
|
|
/*!
|
|
* AES block decryption (ECB mode).
|
|
*
|
|
* \param[out] output Starting address of the decrypted 16-byte block.
|
|
*
|
|
* \param input Starting address of the input 16-byte block.
|
|
*/
|
|
void DecryptBlock( void* output, const void* input ) const;
|
|
|
|
private:
|
|
|
|
uint32 m_erk[ 60 ]; // encryption round keys, 4*(Nr+1) elements
|
|
uint32 m_drk[ 60 ]; // decryption round keys, 4*(Nr+1) elements
|
|
|
|
/*!
|
|
* \internal
|
|
* Sets a new encryption/decryption key. Generates the round key tables and
|
|
* wipes out 32 contiguous bytes starting at \a key.
|
|
*/
|
|
void SetKey( void* key );
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
} // pcl
|
|
|
|
#endif // __PCL_Cryptography_h
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// EOF pcl/Cryptography.h - Released 2022-03-12T18:59:29Z
|