1 | // gcm.h - written and placed in the public domain by Wei Dai |
---|
2 | |
---|
3 | //! \file gcm.h |
---|
4 | //! \brief GCM block cipher mode of operation |
---|
5 | //! \since Crypto++ 5.6.0 |
---|
6 | |
---|
7 | #ifndef CRYPTOPP_GCM_H |
---|
8 | #define CRYPTOPP_GCM_H |
---|
9 | |
---|
10 | #include "authenc.h" |
---|
11 | #include "modes.h" |
---|
12 | |
---|
13 | NAMESPACE_BEGIN(CryptoPP) |
---|
14 | |
---|
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 | |
---|
23 | //! \class GCM_Base |
---|
24 | //! \brief GCM block cipher base implementation |
---|
25 | //! \details Base implementation of the AuthenticatedSymmetricCipher interface |
---|
26 | //! \since Crypto++ 5.6.0 |
---|
27 | class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase |
---|
28 | { |
---|
29 | public: |
---|
30 | // AuthenticatedSymmetricCipher |
---|
31 | std::string AlgorithmName() const |
---|
32 | {return GetBlockCipher().AlgorithmName() + std::string("/GCM");} |
---|
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 | |
---|
59 | protected: |
---|
60 | // AuthenticatedSymmetricCipherBase |
---|
61 | bool AuthenticationIsOnPlaintext() const |
---|
62 | {return false;} |
---|
63 | unsigned int AuthenticationBlockSize() const |
---|
64 | {return HASH_BLOCKSIZE;} |
---|
65 | void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); |
---|
66 | void Resync(const byte *iv, size_t len); |
---|
67 | size_t AuthenticateBlocks(const byte *data, size_t len); |
---|
68 | void AuthenticateLastHeaderBlock(); |
---|
69 | void AuthenticateLastConfidentialBlock(); |
---|
70 | void AuthenticateLastFooterBlock(byte *mac, size_t macSize); |
---|
71 | SymmetricCipher & AccessSymmetricCipher() {return m_ctr;} |
---|
72 | |
---|
73 | virtual BlockCipher & AccessBlockCipher() =0; |
---|
74 | virtual GCM_TablesOption GetTablesOption() const =0; |
---|
75 | |
---|
76 | const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();}; |
---|
77 | byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;} |
---|
78 | byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;} |
---|
79 | byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;} |
---|
80 | inline void ReverseHashBufferIfNeeded(); |
---|
81 | |
---|
82 | class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption |
---|
83 | { |
---|
84 | protected: |
---|
85 | void IncrementCounterBy256(); |
---|
86 | }; |
---|
87 | |
---|
88 | GCTR m_ctr; |
---|
89 | static word16 s_reductionTable[256]; |
---|
90 | static volatile bool s_reductionTableInitialized; |
---|
91 | enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16}; |
---|
92 | }; |
---|
93 | |
---|
94 | //! \class GCM_Final |
---|
95 | //! \brief GCM block cipher final implementation |
---|
96 | //! \tparam T_BlockCipher block cipher |
---|
97 | //! \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables |
---|
98 | //! \tparam T_IsEncryption direction in which to operate the cipher |
---|
99 | //! \since Crypto++ 5.6.0 |
---|
100 | template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption> |
---|
101 | class GCM_Final : public GCM_Base |
---|
102 | { |
---|
103 | public: |
---|
104 | static std::string StaticAlgorithmName() |
---|
105 | {return T_BlockCipher::StaticAlgorithmName() + std::string("/GCM");} |
---|
106 | bool IsForwardTransformation() const |
---|
107 | {return T_IsEncryption;} |
---|
108 | |
---|
109 | private: |
---|
110 | GCM_TablesOption GetTablesOption() const {return T_TablesOption;} |
---|
111 | BlockCipher & AccessBlockCipher() {return m_cipher;} |
---|
112 | typename T_BlockCipher::Encryption m_cipher; |
---|
113 | }; |
---|
114 | |
---|
115 | //! \class GCM |
---|
116 | //! \brief GCM block cipher mode of operation |
---|
117 | //! \tparam T_BlockCipher block cipher |
---|
118 | //! \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables |
---|
119 | //! \details \p GCM provides the \p Encryption and \p Decryption typedef. See GCM_Base |
---|
120 | //! and GCM_Final for the AuthenticatedSymmetricCipher implementation. |
---|
121 | //! \sa <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a> at the Crypto Lounge |
---|
122 | //! \since Crypto++ 5.6.0 |
---|
123 | template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables> |
---|
124 | struct GCM : public AuthenticatedSymmetricCipherDocumentation |
---|
125 | { |
---|
126 | typedef GCM_Final<T_BlockCipher, T_TablesOption, true> Encryption; |
---|
127 | typedef GCM_Final<T_BlockCipher, T_TablesOption, false> Decryption; |
---|
128 | }; |
---|
129 | |
---|
130 | NAMESPACE_END |
---|
131 | |
---|
132 | #endif |
---|