gcm.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // gcm.h - originally written and placed in the public domain by Wei Dai
  2. /// \file gcm.h
  3. /// \brief GCM block cipher mode of operation
  4. /// \since Crypto++ 5.6.0
  5. #ifndef CRYPTOPP_GCM_H
  6. #define CRYPTOPP_GCM_H
  7. #include "authenc.h"
  8. #include "modes.h"
  9. // Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler
  10. // error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232
  11. #if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM)
  12. # define CRYPTOPP_DISABLE_GCM_ASM 1
  13. #endif
  14. NAMESPACE_BEGIN(CryptoPP)
  15. /// \enum GCM_TablesOption
  16. /// \brief GCM table size options
  17. enum GCM_TablesOption {
  18. /// \brief Use a table with 2K entries
  19. GCM_2K_Tables,
  20. /// \brief Use a table with 64K entries
  21. GCM_64K_Tables};
  22. /// \brief GCM block cipher base implementation
  23. /// \details Base implementation of the AuthenticatedSymmetricCipher interface
  24. /// \since Crypto++ 5.6.0
  25. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase
  26. {
  27. public:
  28. // AuthenticatedSymmetricCipher
  29. std::string AlgorithmName() const
  30. {return GetBlockCipher().AlgorithmName() + std::string("/GCM");}
  31. std::string AlgorithmProvider() const
  32. {return GetBlockCipher().AlgorithmProvider();}
  33. size_t MinKeyLength() const
  34. {return GetBlockCipher().MinKeyLength();}
  35. size_t MaxKeyLength() const
  36. {return GetBlockCipher().MaxKeyLength();}
  37. size_t DefaultKeyLength() const
  38. {return GetBlockCipher().DefaultKeyLength();}
  39. size_t GetValidKeyLength(size_t n) const
  40. {return GetBlockCipher().GetValidKeyLength(n);}
  41. bool IsValidKeyLength(size_t n) const
  42. {return GetBlockCipher().IsValidKeyLength(n);}
  43. unsigned int OptimalDataAlignment() const;
  44. IV_Requirement IVRequirement() const
  45. {return UNIQUE_IV;}
  46. unsigned int IVSize() const
  47. {return 12;}
  48. unsigned int MinIVLength() const
  49. {return 1;}
  50. unsigned int MaxIVLength() const
  51. {return UINT_MAX;} // (W64LIT(1)<<61)-1 in the standard
  52. unsigned int DigestSize() const
  53. {return 16;}
  54. lword MaxHeaderLength() const
  55. {return (W64LIT(1)<<61)-1;}
  56. lword MaxMessageLength() const
  57. {return ((W64LIT(1)<<39)-256)/8;}
  58. protected:
  59. // AuthenticatedSymmetricCipherBase
  60. bool AuthenticationIsOnPlaintext() const
  61. {return false;}
  62. unsigned int AuthenticationBlockSize() const
  63. {return HASH_BLOCKSIZE;}
  64. void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs &params);
  65. void Resync(const byte *iv, size_t len);
  66. size_t AuthenticateBlocks(const byte *data, size_t len);
  67. void AuthenticateLastHeaderBlock();
  68. void AuthenticateLastConfidentialBlock();
  69. void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
  70. SymmetricCipher & AccessSymmetricCipher() {return m_ctr;}
  71. virtual BlockCipher & AccessBlockCipher() =0;
  72. virtual GCM_TablesOption GetTablesOption() const =0;
  73. const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();}
  74. byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
  75. byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;}
  76. byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;}
  77. inline void ReverseHashBufferIfNeeded();
  78. class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption
  79. {
  80. protected:
  81. void IncrementCounterBy256();
  82. };
  83. GCTR m_ctr;
  84. static word16 s_reductionTable[256];
  85. static volatile bool s_reductionTableInitialized;
  86. enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16};
  87. };
  88. /// \brief GCM block cipher final implementation
  89. /// \tparam T_BlockCipher block cipher
  90. /// \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables
  91. /// \tparam T_IsEncryption direction in which to operate the cipher
  92. /// \since Crypto++ 5.6.0
  93. template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption>
  94. class GCM_Final : public GCM_Base
  95. {
  96. public:
  97. static std::string StaticAlgorithmName()
  98. {return T_BlockCipher::StaticAlgorithmName() + std::string("/GCM");}
  99. bool IsForwardTransformation() const
  100. {return T_IsEncryption;}
  101. private:
  102. GCM_TablesOption GetTablesOption() const {return T_TablesOption;}
  103. BlockCipher & AccessBlockCipher() {return m_cipher;}
  104. typename T_BlockCipher::Encryption m_cipher;
  105. };
  106. /// \brief GCM block cipher mode of operation
  107. /// \tparam T_BlockCipher block cipher
  108. /// \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables
  109. /// \details \p GCM provides the \p Encryption and \p Decryption typedef. See GCM_Base
  110. /// and GCM_Final for the AuthenticatedSymmetricCipher implementation.
  111. /// \sa <a href="http://www.cryptopp.com/wiki/GCM_Mode">GCM Mode</a> and
  112. /// <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of Operation</A>
  113. /// on the Crypto++ wiki.
  114. /// \since Crypto++ 5.6.0
  115. template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables>
  116. struct GCM : public AuthenticatedSymmetricCipherDocumentation
  117. {
  118. typedef GCM_Final<T_BlockCipher, T_TablesOption, true> Encryption;
  119. typedef GCM_Final<T_BlockCipher, T_TablesOption, false> Decryption;
  120. };
  121. NAMESPACE_END
  122. #endif