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 | |
---|
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 n) const |
---|
35 | {return GetBlockCipher().GetValidKeyLength(n);} |
---|
36 | bool IsValidKeyLength(size_t n) const |
---|
37 | {return GetBlockCipher().IsValidKeyLength(n);} |
---|
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: |
---|
94 | static std::string StaticAlgorithmName() |
---|
95 | {return T_BlockCipher::StaticAlgorithmName() + std::string("/CCM");} |
---|
96 | bool IsForwardTransformation() const |
---|
97 | {return T_IsEncryption;} |
---|
98 | |
---|
99 | private: |
---|
100 | BlockCipher & AccessBlockCipher() {return m_cipher;} |
---|
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 |
---|