PCL
Cryptography.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.7.0
6 // ----------------------------------------------------------------------------
7 // pcl/Cryptography.h - Released 2024-06-18T15:48:54Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2024 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_Cryptography_h
53 #define __PCL_Cryptography_h
54 
56 
57 #include <pcl/Defs.h>
58 #include <pcl/Diagnostics.h>
59 
60 #include <pcl/AutoPointer.h>
61 #include <pcl/ByteArray.h>
62 #include <pcl/Exception.h>
63 #include <pcl/String.h>
64 
65 namespace pcl
66 {
67 
68 // ----------------------------------------------------------------------------
69 
85 class PCL_CLASS CryptographicHash
86 {
87 public:
88 
92  CryptographicHash() = default;
93 
98  {
99  }
100 
106 
111  CryptographicHash& operator =( const CryptographicHash& ) = delete;
112 
116  virtual String AlgorithmName() const = 0;
117 
122  virtual size_type HashLength() const = 0;
123 
127  virtual void Initialize() = 0;
128 
133  virtual void Update( const void* data, size_type length ) = 0;
134 
144  template <class C>
145  void UpdateWithContainer( const C& data )
146  {
147  Update( data.Begin(), data.Size() );
148  }
149 
155  {
156  ByteArray hash( HashLength() );
157  DoFinalize( hash.Begin() );
158  return hash;
159  }
160 
168  void Hash( uint8* hash, const void* data, size_type length )
169  {
170  Initialize();
171  Update( data, length );
172  DoFinalize( hash );
173  }
174 
179  ByteArray Hash( const void* data, size_type length )
180  {
181  ByteArray hash( HashLength() );
182  Hash( hash.Begin(), data, length );
183  return hash;
184  }
185 
195  template <class C>
196  ByteArray Hash( const C& data )
197  {
198  return Hash( data.Begin(), data.Size() );
199  }
200 
201 protected:
202 
209  virtual void DoFinalize( void* hash ) = 0;
210 
211  friend class CryptographicHashFactory;
212 };
213 
214 // ----------------------------------------------------------------------------
215 
233 class PCL_CLASS MD5 : public CryptographicHash
234 {
235 public:
236 
240  MD5() = default;
241 
245  ~MD5() override;
246 
250  String AlgorithmName() const override
251  {
252  return "MD5";
253  }
254 
262  size_type HashLength() const override
263  {
264  return 16;
265  }
266 
269  void Initialize() override;
270 
273  void Update( const void* data, size_type length ) override;
274 
275 private:
276 
277  void* m_context = nullptr;
278 
281  void DoFinalize( void* hash ) override;
282 };
283 
284 // ----------------------------------------------------------------------------
285 
305 class PCL_CLASS SHA1 : public CryptographicHash
306 {
307 public:
308 
312  SHA1() = default;
313 
317  ~SHA1() override;
318 
322  String AlgorithmName() const override
323  {
324  return "SHA1";
325  }
326 
334  size_type HashLength() const override
335  {
336  return 20;
337  }
338 
341  void Initialize() override;
342 
345  void Update( const void* data, size_type length ) override;
346 
347 private:
348 
349  void* m_context = nullptr; // RFC4634
350 
353  void DoFinalize( void* hash ) override;
354 };
355 
356 // ----------------------------------------------------------------------------
357 
377 class PCL_CLASS SHA224 : public CryptographicHash
378 {
379 public:
380 
384  SHA224() = default;
385 
389  ~SHA224() override;
390 
394  String AlgorithmName() const override
395  {
396  return "SHA224";
397  }
398 
406  size_type HashLength() const override
407  {
408  return 28;
409  }
410 
413  void Initialize() override;
414 
417  void Update( const void* data, size_type length ) override;
418 
419 private:
420 
421  void* m_context = nullptr; // RFC4634
422 
425  void DoFinalize( void* hash ) override;
426 };
427 
428 // ----------------------------------------------------------------------------
429 
448 class PCL_CLASS SHA256 : public CryptographicHash
449 {
450 public:
451 
455  SHA256() = default;
456 
460  ~SHA256() override;
461 
465  String AlgorithmName() const override
466  {
467  return "SHA256";
468  }
469 
477  size_type HashLength() const override
478  {
479  return 32;
480  }
481 
484  void Initialize() override;
485 
488  void Update( const void* data, size_type length ) override;
489 
490 private:
491 
492  void* m_context = nullptr; // RFC4634
493 
496  void DoFinalize( void* hash ) override;
497 };
498 
499 // ----------------------------------------------------------------------------
500 
519 class PCL_CLASS SHA384 : public CryptographicHash
520 {
521 public:
522 
526  SHA384() = default;
527 
531  ~SHA384() override;
532 
536  String AlgorithmName() const override
537  {
538  return "SHA384";
539  }
540 
548  size_type HashLength() const override
549  {
550  return 48;
551  }
552 
555  void Initialize() override;
556 
559  void Update( const void* data, size_type length ) override;
560 
561 private:
562 
563  void* m_context = nullptr; // RFC4634
564 
567  void DoFinalize( void* hash ) override;
568 };
569 
570 // ----------------------------------------------------------------------------
571 
590 class PCL_CLASS SHA512 : public CryptographicHash
591 {
592 public:
593 
597  SHA512() = default;
598 
602  ~SHA512() override;
603 
607  String AlgorithmName() const override
608  {
609  return "SHA512";
610  }
611 
619  size_type HashLength() const override
620  {
621  return 64;
622  }
623 
626  void Initialize() override;
627 
630  void Update( const void* data, size_type length ) override;
631 
632 private:
633 
634  void* m_context = nullptr; // RFC4634
635 
638  void DoFinalize( void* hash ) override;
639 };
640 
641 // ----------------------------------------------------------------------------
642 
656 {
657 public:
658 
672  CryptographicHashFactory( const IsoString& algorithmName )
673  {
674  switch ( algorithmName.Trimmed().CaseFolded().Hash32() )
675  {
676  case 0x445dd715: m_hash = new MD5; break;
677  case 0x3cac24af: m_hash = new SHA1; break;
678  case 0x7e50b015: m_hash = new SHA224; break;
679  case 0xcbbce793: m_hash = new SHA256; break;
680  case 0x858a0d3d: m_hash = new SHA384; break;
681  case 0xb24dfd53: m_hash = new SHA512; break;
682  default:
683  throw Error( "CryptographicHashFactory: Unknown/unsupported algorithm \'" + algorithmName + '\'' );
684  }
685  }
686 
687  CryptographicHashFactory( const IsoString::ustring_base& algorithmName )
688  : CryptographicHashFactory( IsoString( algorithmName ) )
689  {
690  }
691 
696  {
697  }
698 
702  String AlgorithmName() const override
703  {
704  return m_hash->AlgorithmName();
705  }
706 
711  size_type HashLength() const override
712  {
713  return m_hash->HashLength();
714  }
715 
719  void Initialize() override
720  {
721  m_hash->Initialize();
722  }
723 
728  void Update( const void* data, size_type length ) override
729  {
730  m_hash->Update( data, length );
731  }
732 
733 private:
734 
736 
737  void DoFinalize( void* hash ) override
738  {
739  m_hash->DoFinalize( hash );
740  }
741 };
742 
743 // ----------------------------------------------------------------------------
744 
758 class PCL_CLASS Cipher
759 {
760 public:
761 
765  Cipher() = default;
766 
770  Cipher( const Cipher& ) = default;
771 
775  Cipher& operator =( const Cipher& ) = default;
776 
780  virtual ~Cipher()
781  {
782  }
783 
787  virtual String AlgorithmName() const = 0;
788 
792  virtual size_type KeyLength() const = 0;
793 
805  virtual void Encrypt( void* output, const void* input, size_type length ) const = 0;
806 
818  virtual void Decrypt( void* output, const void* input, size_type length ) const = 0;
819 
836  template <class C>
837  void Encrypt( void* output, const C& input ) const
838  {
839  Encrypt( output, input.Begin(), input.Size() );
840  }
841 
859  template <class C>
860  ByteArray Encrypt( const C& input ) const
861  {
862  ByteArray output( input.Size() );
863  Encrypt( output.Begin(), input.Begin(), input.Size() );
864  return output;
865  }
866 
883  template <class C>
884  void Decrypt( void* output, const C& input ) const
885  {
886  Decrypt( output, input.Begin(), input.Size() );
887  }
888 
905  template <class C>
906  ByteArray Decrypt( const C& input ) const
907  {
908  ByteArray output( input.Size() );
909  Decrypt( output.Begin(), input.Begin(), input.Size() );
910  return output;
911  }
912 };
913 
914 // ----------------------------------------------------------------------------
915 
933 class PCL_CLASS AES256 : public Cipher
934 {
935 public:
936 
937  enum { key_length = 32, block_length = 16 };
938 
942  using key_type = uint8[ key_length ];
943 
948  using block_type = uint8[ block_length ];
949 
963  AES256( void* key )
964  {
965  SetKey( key );
966  }
967 
987  {
988  ByteArray h = MD5().Hash( key );
989  key.SecureFill();
990  for ( int i = 1; i < 20; ++i )
991  h = MD5().Hash( h );
992  IsoString k = IsoString::ToHex( h );
993  h.Fill( uint8( 0 ) );
994  SetKey( k.Begin() );
995  }
996 
1000  AES256( const AES256& ) = default;
1001 
1005  AES256& operator =( const AES256& ) = default;
1006 
1010  ~AES256() override
1011  {
1012  }
1013 
1017  String AlgorithmName() const override
1018  {
1019  return "AES256";
1020  }
1021 
1025  size_type KeyLength() const override
1026  {
1027  return 32;
1028  }
1029 
1046  void Encrypt( void* output, const void* input, size_type length ) const override;
1047 
1063  void Decrypt( void* output, const void* input, size_type length ) const override;
1064 
1072  void EncryptBlock( void* output, const void* input ) const;
1073 
1081  void DecryptBlock( void* output, const void* input ) const;
1082 
1083 private:
1084 
1085  uint32 m_erk[ 60 ]; // encryption round keys, 4*(Nr+1) elements
1086  uint32 m_drk[ 60 ]; // decryption round keys, 4*(Nr+1) elements
1087 
1093  void SetKey( void* key );
1094 };
1095 
1096 // ----------------------------------------------------------------------------
1097 
1098 } // pcl
1099 
1100 #endif // __PCL_Cryptography_h
1101 
1102 // ----------------------------------------------------------------------------
1103 // EOF pcl/Cryptography.h - Released 2024-06-18T15:48:54Z
AES-256 cipher.
Definition: Cryptography.h:934
String AlgorithmName() const override
~AES256() override
void Decrypt(void *output, const void *input, size_type length) const override
AES256(IsoString &key)
Definition: Cryptography.h:986
AES256(const AES256 &)=default
size_type KeyLength() const override
AES256(void *key)
Definition: Cryptography.h:963
uint8[block_length] block_type
Definition: Cryptography.h:948
void DecryptBlock(void *output, const void *input) const
void Encrypt(void *output, const void *input, size_type length) const override
void EncryptBlock(void *output, const void *input) const
uint8[key_length] key_type
Definition: Cryptography.h:942
iterator Begin()
Definition: Array.h:426
void Fill(const T &v)
Definition: Array.h:1362
A smart pointer with exclusive object ownership and optional automatic object destruction.
Definition: AutoPointer.h:241
Abstract base class for cipher algorithm implementations.
Definition: Cryptography.h:759
virtual void Encrypt(void *output, const void *input, size_type length) const =0
virtual void Decrypt(void *output, const void *input, size_type length) const =0
ByteArray Decrypt(const C &input) const
Definition: Cryptography.h:906
void Encrypt(void *output, const C &input) const
Definition: Cryptography.h:837
virtual String AlgorithmName() const =0
virtual ~Cipher()
Definition: Cryptography.h:780
void Decrypt(void *output, const C &input) const
Definition: Cryptography.h:884
Cipher()=default
Cipher(const Cipher &)=default
ByteArray Encrypt(const C &input) const
Definition: Cryptography.h:860
virtual size_type KeyLength() const =0
Selectable cryptographic hashing algorithm.
Definition: Cryptography.h:656
CryptographicHashFactory(const IsoString &algorithmName)
Definition: Cryptography.h:672
void Update(const void *data, size_type length) override
Definition: Cryptography.h:728
size_type HashLength() const override
Definition: Cryptography.h:711
String AlgorithmName() const override
Definition: Cryptography.h:702
Abstract base class for cryptographic hashing algorithm implementations.
Definition: Cryptography.h:86
virtual void DoFinalize(void *hash)=0
virtual String AlgorithmName() const =0
virtual ~CryptographicHash()
Definition: Cryptography.h:97
ByteArray Hash(const void *data, size_type length)
Definition: Cryptography.h:179
void UpdateWithContainer(const C &data)
Definition: Cryptography.h:145
ByteArray Hash(const C &data)
Definition: Cryptography.h:196
virtual size_type HashLength() const =0
CryptographicHash(const CryptographicHash &)=delete
virtual void Update(const void *data, size_type length)=0
virtual void Initialize()=0
void Hash(uint8 *hash, const void *data, size_type length)
Definition: Cryptography.h:168
A simple exception with an associated error message.
Definition: Exception.h:239
iterator Begin()
Definition: String.h:976
void SecureFill(char c='\0') noexcept
Definition: String.h:1448
uint32 Hash32(uint32 seed=0) const noexcept
Definition: String.h:4245
Eight-bit string (ISO/IEC-8859-1 or UTF-8 string)
Definition: String.h:5425
static IsoString ToHex(const void *data, size_type length)
Implementation of the MD5 cryptographic hashing algorithm.
Definition: Cryptography.h:234
String AlgorithmName() const override
Definition: Cryptography.h:250
size_type HashLength() const override
Definition: Cryptography.h:262
MD5()=default
void Update(const void *data, size_type length) override
~MD5() override
void Initialize() override
Implementation of the SHA-1 cryptographic hashing algorithm.
Definition: Cryptography.h:306
SHA1()=default
size_type HashLength() const override
Definition: Cryptography.h:334
~SHA1() override
void Initialize() override
String AlgorithmName() const override
Definition: Cryptography.h:322
void Update(const void *data, size_type length) override
Implementation of the SHA-224 cryptographic hashing algorithm.
Definition: Cryptography.h:378
SHA224()=default
~SHA224() override
size_type HashLength() const override
Definition: Cryptography.h:406
void Initialize() override
void Update(const void *data, size_type length) override
String AlgorithmName() const override
Definition: Cryptography.h:394
Implementation of the SHA-256 cryptographic hashing algorithm.
Definition: Cryptography.h:449
void Initialize() override
void Update(const void *data, size_type length) override
~SHA256() override
size_type HashLength() const override
Definition: Cryptography.h:477
SHA256()=default
String AlgorithmName() const override
Definition: Cryptography.h:465
Implementation of the SHA-384 cryptographic hashing algorithm.
Definition: Cryptography.h:520
String AlgorithmName() const override
Definition: Cryptography.h:536
~SHA384() override
SHA384()=default
void Update(const void *data, size_type length) override
void Initialize() override
size_type HashLength() const override
Definition: Cryptography.h:548
Implementation of the SHA-512 cryptographic hashing algorithm.
Definition: Cryptography.h:591
SHA512()=default
void Initialize() override
~SHA512() override
size_type HashLength() const override
Definition: Cryptography.h:619
void Update(const void *data, size_type length) override
String AlgorithmName() const override
Definition: Cryptography.h:607
Unicode (UTF-16) string.
Definition: String.h:8113
unsigned char uint8
Definition: Defs.h:642
unsigned int uint32
Definition: Defs.h:666
size_t size_type
Definition: Defs.h:609
PCL root namespace.
Definition: AbstractImage.h:77