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