1#ifndef CRYPTOPP_GCM_H
2#define CRYPTOPP_GCM_H
3
4#include "authenc.h"
5#include "modes.h"
6
7NAMESPACE_BEGIN(CryptoPP)
8
9//! .
10enum GCM_TablesOption {GCM_2K_Tables, GCM_64K_Tables};
11
12//! .
13class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase
14{
15public:
16	// AuthenticatedSymmetricCipher
17	std::string AlgorithmName() const
18		{return GetBlockCipher().AlgorithmName() + std::string("/GCM");}
19	size_t MinKeyLength() const
20		{return GetBlockCipher().MinKeyLength();}
21	size_t MaxKeyLength() const
22		{return GetBlockCipher().MaxKeyLength();}
23	size_t DefaultKeyLength() const
24		{return GetBlockCipher().DefaultKeyLength();}
25	size_t GetValidKeyLength(size_t n) const
26		{return GetBlockCipher().GetValidKeyLength(n);}
27	bool IsValidKeyLength(size_t n) const
28		{return GetBlockCipher().IsValidKeyLength(n);}
29	unsigned int OptimalDataAlignment() const;
30	IV_Requirement IVRequirement() const
31		{return UNIQUE_IV;}
32	unsigned int IVSize() const
33		{return 12;}
34	unsigned int MinIVLength() const
35		{return 1;}
36	unsigned int MaxIVLength() const
37		{return UINT_MAX;}		// (W64LIT(1)<<61)-1 in the standard
38	unsigned int DigestSize() const
39		{return 16;}
40	lword MaxHeaderLength() const
41		{return (W64LIT(1)<<61)-1;}
42	lword MaxMessageLength() const
43		{return ((W64LIT(1)<<39)-256)/8;}
44
45protected:
46	// AuthenticatedSymmetricCipherBase
47	bool AuthenticationIsOnPlaintext() const
48		{return false;}
49	unsigned int AuthenticationBlockSize() const
50		{return HASH_BLOCKSIZE;}
51	void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs &params);
52	void Resync(const byte *iv, size_t len);
53	size_t AuthenticateBlocks(const byte *data, size_t len);
54	void AuthenticateLastHeaderBlock();
55	void AuthenticateLastConfidentialBlock();
56	void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
57	SymmetricCipher & AccessSymmetricCipher() {return m_ctr;}
58
59	virtual BlockCipher & AccessBlockCipher() =0;
60	virtual GCM_TablesOption GetTablesOption() const =0;
61
62	const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();};
63	byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
64	byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;}
65	byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;}
66
67	class GCTR : public CTR_Mode_ExternalCipher::Encryption
68	{
69	protected:
70		void IncrementCounterBy256();
71	};
72
73	GCTR m_ctr;
74	static word16 s_reductionTable[256];
75	static bool s_reductionTableInitialized;
76	enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16};
77};
78
79//! .
80template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption>
81class GCM_Final : public GCM_Base
82{
83public:
84	static std::string StaticAlgorithmName()
85		{return T_BlockCipher::StaticAlgorithmName() + std::string("/GCM");}
86	bool IsForwardTransformation() const
87		{return T_IsEncryption;}
88
89private:
90	GCM_TablesOption GetTablesOption() const {return T_TablesOption;}
91	BlockCipher & AccessBlockCipher() {return m_cipher;}
92	typename T_BlockCipher::Encryption m_cipher;
93};
94
95//! <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a>
96template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables>
97struct GCM : public AuthenticatedSymmetricCipherDocumentation
98{
99	typedef GCM_Final<T_BlockCipher, T_TablesOption, true> Encryption;
100	typedef GCM_Final<T_BlockCipher, T_TablesOption, false> Decryption;
101};
102
103NAMESPACE_END
104
105#endif
106