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 ¶ms);
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