5 #ifndef CRYPTOPP_IMPORTS 15 blockCipher.
SetKey(userKey, keylength, params);
17 if (blockCipher.
BlockSize() != REQUIRED_BLOCKSIZE)
18 throw InvalidArgument(AlgorithmName() +
": block size of underlying block cipher is not 16");
20 m_digestSize = params.GetIntValueWithDefault(
Name::DigestSize(), DefaultDigestSize());
21 if (m_digestSize % 2 > 0 || m_digestSize < 4 || m_digestSize > 16)
22 throw InvalidArgument(AlgorithmName() +
": DigestSize must be 4, 6, 8, 10, 12, 14, or 16");
24 m_buffer.Grow(2*REQUIRED_BLOCKSIZE);
28 void CCM_Base::Resync(
const byte *iv,
size_t len)
32 m_L = REQUIRED_BLOCKSIZE-1-(int)len;
37 m_buffer[0] = byte(m_L-1);
38 memcpy(m_buffer+1, iv, len);
39 memset(m_buffer+1+len, 0, REQUIRED_BLOCKSIZE-1-len);
41 if (m_state >= State_IVSet)
42 m_ctr.Resynchronize(m_buffer, REQUIRED_BLOCKSIZE);
44 m_ctr.SetCipherWithIV(cipher, m_buffer);
46 m_ctr.Seek(REQUIRED_BLOCKSIZE);
51 void CCM_Base::UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword )
53 if (m_state != State_IVSet)
54 throw BadState(
AlgorithmName(),
"SpecifyDataLengths",
"or after State_IVSet");
56 m_aadLength = headerLength;
57 m_messageLength = messageLength;
59 byte *cbcBuffer = CBC_Buffer();
62 cbcBuffer[0] = byte(64*(headerLength>0) + 8*((m_digestSize-2)/2) + (m_L-1));
63 PutWord<word64>(
true, BIG_ENDIAN_ORDER, cbcBuffer+REQUIRED_BLOCKSIZE-8, m_messageLength);
64 memcpy(cbcBuffer+1, m_buffer+1, REQUIRED_BLOCKSIZE-1-m_L);
69 assert(m_bufferedDataLength == 0);
71 if (headerLength < ((1<<16) - (1<<8)))
73 PutWord<word16>(
true, BIG_ENDIAN_ORDER, m_buffer, (word16)headerLength);
74 m_bufferedDataLength = 2;
76 else if (headerLength < (W64LIT(1)<<32))
80 PutWord<word32>(
false, BIG_ENDIAN_ORDER, m_buffer+2, (word32)headerLength);
81 m_bufferedDataLength = 6;
87 PutWord<word64>(
false, BIG_ENDIAN_ORDER, m_buffer+2, headerLength);
88 m_bufferedDataLength = 10;
93 size_t CCM_Base::AuthenticateBlocks(
const byte *data,
size_t len)
95 byte *cbcBuffer = CBC_Buffer();
100 void CCM_Base::AuthenticateLastHeaderBlock()
102 byte *cbcBuffer = CBC_Buffer();
105 if (m_aadLength != m_totalHeaderLength)
108 if (m_bufferedDataLength > 0)
110 xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength);
112 m_bufferedDataLength = 0;
116 void CCM_Base::AuthenticateLastConfidentialBlock()
118 byte *cbcBuffer = CBC_Buffer();
121 if (m_messageLength != m_totalMessageLength)
124 if (m_bufferedDataLength > 0)
126 xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength);
128 m_bufferedDataLength = 0;
132 void CCM_Base::AuthenticateLastFooterBlock(byte *mac,
size_t macSize)
135 m_ctr.ProcessData(mac, CBC_Buffer(), macSize);
std::string AlgorithmName() const
Provides the name of this algorithm.
const char * DigestSize()
int, in bytes
An invalid argument was detected.
virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms=g_nullNameValuePairs)
Sets or reset the key of this object.
Interface for one direction (encryption or decryption) of a block cipher.
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Crypto++ library namespace.
CCM block cipher mode of operation.
Interface for retrieving values given their names.