Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:03

0001 // gcm.h - originally written and placed in the public domain by Wei Dai

0002 
0003 /// \file gcm.h

0004 /// \brief GCM block cipher mode of operation

0005 /// \since Crypto++ 5.6.0

0006 
0007 #ifndef CRYPTOPP_GCM_H
0008 #define CRYPTOPP_GCM_H
0009 
0010 #include "authenc.h"
0011 #include "modes.h"
0012 
0013 // Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler

0014 // error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232

0015 #if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM)
0016 # define CRYPTOPP_DISABLE_GCM_ASM 1
0017 #endif
0018 
0019 NAMESPACE_BEGIN(CryptoPP)
0020 
0021 /// \enum GCM_TablesOption

0022 /// \brief GCM table size options

0023 enum GCM_TablesOption {
0024     /// \brief Use a table with 2K entries

0025     GCM_2K_Tables,
0026     /// \brief Use a table with 64K entries

0027     GCM_64K_Tables};
0028 
0029 /// \brief GCM block cipher base implementation

0030 /// \details Base implementation of the AuthenticatedSymmetricCipher interface

0031 /// \since Crypto++ 5.6.0

0032 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase
0033 {
0034 public:
0035     // AuthenticatedSymmetricCipher

0036     std::string AlgorithmName() const
0037         {return GetBlockCipher().AlgorithmName() + std::string("/GCM");}
0038     std::string AlgorithmProvider() const
0039         {return GetBlockCipher().AlgorithmProvider();}
0040     size_t MinKeyLength() const
0041         {return GetBlockCipher().MinKeyLength();}
0042     size_t MaxKeyLength() const
0043         {return GetBlockCipher().MaxKeyLength();}
0044     size_t DefaultKeyLength() const
0045         {return GetBlockCipher().DefaultKeyLength();}
0046     size_t GetValidKeyLength(size_t n) const
0047         {return GetBlockCipher().GetValidKeyLength(n);}
0048     bool IsValidKeyLength(size_t n) const
0049         {return GetBlockCipher().IsValidKeyLength(n);}
0050     unsigned int OptimalDataAlignment() const;
0051     IV_Requirement IVRequirement() const
0052         {return UNIQUE_IV;}
0053     unsigned int IVSize() const
0054         {return 12;}
0055     unsigned int MinIVLength() const
0056         {return 1;}
0057     unsigned int MaxIVLength() const
0058         {return UINT_MAX;}      // (W64LIT(1)<<61)-1 in the standard

0059     unsigned int DigestSize() const
0060         {return 16;}
0061     lword MaxHeaderLength() const
0062         {return (W64LIT(1)<<61)-1;}
0063     lword MaxMessageLength() const
0064         {return ((W64LIT(1)<<39)-256)/8;}
0065 
0066 protected:
0067     // AuthenticatedSymmetricCipherBase

0068     bool AuthenticationIsOnPlaintext() const
0069         {return false;}
0070     unsigned int AuthenticationBlockSize() const
0071         {return HASH_BLOCKSIZE;}
0072     void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs &params);
0073     void Resync(const byte *iv, size_t len);
0074     size_t AuthenticateBlocks(const byte *data, size_t len);
0075     void AuthenticateLastHeaderBlock();
0076     void AuthenticateLastConfidentialBlock();
0077     void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
0078     SymmetricCipher & AccessSymmetricCipher() {return m_ctr;}
0079 
0080     virtual BlockCipher & AccessBlockCipher() =0;
0081     virtual GCM_TablesOption GetTablesOption() const =0;
0082 
0083     const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();}
0084     byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
0085     byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;}
0086     byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;}
0087     inline void ReverseHashBufferIfNeeded();
0088 
0089     class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption
0090     {
0091     protected:
0092         void IncrementCounterBy256();
0093     };
0094 
0095     GCTR m_ctr;
0096     static word16 s_reductionTable[256];
0097     static volatile bool s_reductionTableInitialized;
0098     enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16};
0099 };
0100 
0101 /// \brief GCM block cipher final implementation

0102 /// \tparam T_BlockCipher block cipher

0103 /// \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables

0104 /// \tparam T_IsEncryption direction in which to operate the cipher

0105 /// \since Crypto++ 5.6.0

0106 template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption>
0107 class GCM_Final : public GCM_Base
0108 {
0109 public:
0110     static std::string StaticAlgorithmName()
0111         {return T_BlockCipher::StaticAlgorithmName() + std::string("/GCM");}
0112     bool IsForwardTransformation() const
0113         {return T_IsEncryption;}
0114 
0115 private:
0116     GCM_TablesOption GetTablesOption() const {return T_TablesOption;}
0117     BlockCipher & AccessBlockCipher() {return m_cipher;}
0118     typename T_BlockCipher::Encryption m_cipher;
0119 };
0120 
0121 /// \brief GCM block cipher mode of operation

0122 /// \tparam T_BlockCipher block cipher

0123 /// \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables

0124 /// \details \p GCM provides the \p Encryption and \p Decryption typedef. See GCM_Base

0125 ///   and GCM_Final for the AuthenticatedSymmetricCipher implementation.

0126 /// \sa <a href="http://www.cryptopp.com/wiki/GCM_Mode">GCM Mode</a> and

0127 ///   <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of Operation</A>

0128 ///   on the Crypto++ wiki.

0129 /// \since Crypto++ 5.6.0

0130 template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables>
0131 struct GCM : public AuthenticatedSymmetricCipherDocumentation
0132 {
0133     typedef GCM_Final<T_BlockCipher, T_TablesOption, true> Encryption;
0134     typedef GCM_Final<T_BlockCipher, T_TablesOption, false> Decryption;
0135 };
0136 
0137 NAMESPACE_END
0138 
0139 #endif