1 // ccm.h - written and placed in the public domain by Wei Dai
2 
3 //! \file ccm.h
4 //! \brief CCM block cipher mode of operation
5 //! \since Crypto++ 5.6.0
6 
7 #ifndef CRYPTOPP_CCM_H
8 #define CRYPTOPP_CCM_H
9 
10 #include "authenc.h"
11 #include "modes.h"
12 
NAMESPACE_BEGIN(CryptoPP)13 NAMESPACE_BEGIN(CryptoPP)
14 
15 //! \class CCM_Base
16 //! \brief CCM block cipher base implementation
17 //! \details Base implementation of the AuthenticatedSymmetricCipher interface
18 //! \since Crypto++ 5.6.0
19 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CCM_Base : public AuthenticatedSymmetricCipherBase
20 {
21 public:
22 	CCM_Base()
23 		: m_digestSize(0), m_L(0), m_messageLength(0), m_aadLength(0) {}
24 
25 	// AuthenticatedSymmetricCipher
26 	std::string AlgorithmName() const
27 		{return GetBlockCipher().AlgorithmName() + std::string("/CCM");}
28 	size_t MinKeyLength() const
29 		{return GetBlockCipher().MinKeyLength();}
30 	size_t MaxKeyLength() const
31 		{return GetBlockCipher().MaxKeyLength();}
32 	size_t DefaultKeyLength() const
33 		{return GetBlockCipher().DefaultKeyLength();}
34 	size_t GetValidKeyLength(size_t keylength) const
35 		{return GetBlockCipher().GetValidKeyLength(keylength);}
36 	bool IsValidKeyLength(size_t keylength) const
37 		{return GetBlockCipher().IsValidKeyLength(keylength);}
38 	unsigned int OptimalDataAlignment() const
39 		{return GetBlockCipher().OptimalDataAlignment();}
40 	IV_Requirement IVRequirement() const
41 		{return UNIQUE_IV;}
42 	unsigned int IVSize() const
43 		{return 8;}
44 	unsigned int MinIVLength() const
45 		{return 7;}
46 	unsigned int MaxIVLength() const
47 		{return 13;}
48 	unsigned int DigestSize() const
49 		{return m_digestSize;}
50 	lword MaxHeaderLength() const
51 		{return W64LIT(0)-1;}
52 	lword MaxMessageLength() const
53 		{return m_L<8 ? (W64LIT(1)<<(8*m_L))-1 : W64LIT(0)-1;}
54 	bool NeedsPrespecifiedDataLengths() const
55 		{return true;}
56 	void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength);
57 
58 protected:
59 	// AuthenticatedSymmetricCipherBase
60 	bool AuthenticationIsOnPlaintext() const
61 		{return true;}
62 	unsigned int AuthenticationBlockSize() const
63 		{return GetBlockCipher().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 
72 	virtual BlockCipher & AccessBlockCipher() =0;
73 	virtual int DefaultDigestSize() const =0;
74 
75 	const BlockCipher & GetBlockCipher() const {return const_cast<CCM_Base *>(this)->AccessBlockCipher();};
76 	byte *CBC_Buffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
77 
78 	enum {REQUIRED_BLOCKSIZE = 16};
79 	int m_digestSize, m_L;
80 	word64 m_messageLength, m_aadLength;
81 	CTR_Mode_ExternalCipher::Encryption m_ctr;
82 };
83 
84 //! \class CCM_Final
85 //! \brief CCM block cipher final implementation
86 //! \tparam T_BlockCipher block cipher
87 //! \tparam T_DefaultDigestSize default digest size, in bytes
88 //! \tparam T_IsEncryption direction in which to operate the cipher
89 //! \since Crypto++ 5.6.0
90 template <class T_BlockCipher, int T_DefaultDigestSize, bool T_IsEncryption>
91 class CCM_Final : public CCM_Base
92 {
93 public:
StaticAlgorithmName()94 	static std::string StaticAlgorithmName()
95 		{return T_BlockCipher::StaticAlgorithmName() + std::string("/CCM");}
IsForwardTransformation()96 	bool IsForwardTransformation() const
97 		{return T_IsEncryption;}
98 
99 private:
AccessBlockCipher()100 	BlockCipher & AccessBlockCipher() {return m_cipher;}
DefaultDigestSize()101 	int DefaultDigestSize() const {return T_DefaultDigestSize;}
102 	typename T_BlockCipher::Encryption m_cipher;
103 };
104 
105 //! \class CCM
106 //! \brief CCM block cipher mode of operation
107 //! \tparam T_BlockCipher block cipher
108 //! \tparam T_DefaultDigestSize default digest size, in bytes
109 //! \details \p CCM 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.cryptolounge.org/wiki/CCM">CCM</a> at the Crypto Lounge
112 //! \since Crypto++ 5.6.0
113 template <class T_BlockCipher, int T_DefaultDigestSize = 16>
114 struct CCM : public AuthenticatedSymmetricCipherDocumentation
115 {
116 	typedef CCM_Final<T_BlockCipher, T_DefaultDigestSize, true> Encryption;
117 	typedef CCM_Final<T_BlockCipher, T_DefaultDigestSize, false> Decryption;
118 };
119 
120 NAMESPACE_END
121 
122 #endif
123