dmac.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // dmac.h - originally written and placed in the public domain by Wei Dai
  2. /// \file dmac.h
  3. /// \brief Classes for DMAC message authentication code
  4. #ifndef CRYPTOPP_DMAC_H
  5. #define CRYPTOPP_DMAC_H
  6. #include "cbcmac.h"
  7. NAMESPACE_BEGIN(CryptoPP)
  8. /// \brief DMAC message authentication code base class
  9. /// \tparam T class derived from BlockCipherDocumentation
  10. /// \since Crypto++ 3.1
  11. template <class T>
  12. class CRYPTOPP_NO_VTABLE DMAC_Base : public SameKeyLengthAs<T>, public MessageAuthenticationCode
  13. {
  14. public:
  15. CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE);
  16. static std::string StaticAlgorithmName() {return std::string("DMAC(") + T::StaticAlgorithmName() + ")";}
  17. virtual~DMAC_Base() {}
  18. DMAC_Base() : m_subkeylength(0), m_counter(0) {}
  19. void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
  20. void Update(const byte *input, size_t length);
  21. void TruncatedFinal(byte *mac, size_t size);
  22. unsigned int DigestSize() const {return DIGESTSIZE;}
  23. std::string AlgorithmProvider() const;
  24. private:
  25. byte *GenerateSubKeys(const byte *key, size_t keylength);
  26. size_t m_subkeylength;
  27. SecByteBlock m_subkeys;
  28. CBC_MAC<T> m_mac1;
  29. typename T::Encryption m_f2;
  30. unsigned int m_counter;
  31. };
  32. template <class T>
  33. std::string DMAC_Base<T>::AlgorithmProvider() const
  34. {
  35. return m_f2.AlgorithmProvider();
  36. }
  37. /// \brief DMAC message authentication code
  38. /// \tparam T class derived from BlockCipherDocumentation
  39. /// \sa <A HREF="https://eprint.iacr.org/1997/010">CBC MAC for Real-Time Data Sources (08.15.1997)</A>
  40. /// by Erez Petrank and Charles Rackoff
  41. /// \since Crypto++ 3.1
  42. template <class T>
  43. class DMAC : public MessageAuthenticationCodeFinal<DMAC_Base<T> >
  44. {
  45. public:
  46. /// \brief Construct a DMAC
  47. DMAC() {}
  48. /// \brief Construct a DMAC
  49. /// \param key a byte array used to key the cipher
  50. /// \param length the size of the byte array, in bytes
  51. DMAC(const byte *key, size_t length=DMAC_Base<T>::DEFAULT_KEYLENGTH)
  52. {this->SetKey(key, length);}
  53. };
  54. template <class T>
  55. void DMAC_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
  56. {
  57. m_subkeylength = T::StaticGetValidKeyLength(T::BLOCKSIZE);
  58. m_subkeys.resize(2*UnsignedMin((unsigned int)T::BLOCKSIZE, m_subkeylength));
  59. m_mac1.SetKey(GenerateSubKeys(key, length), m_subkeylength, params);
  60. m_f2.SetKey(m_subkeys+m_subkeys.size()/2, m_subkeylength, params);
  61. m_counter = 0;
  62. m_subkeys.resize(0);
  63. }
  64. template <class T>
  65. void DMAC_Base<T>::Update(const byte *input, size_t length)
  66. {
  67. m_mac1.Update(input, length);
  68. m_counter = (unsigned int)((m_counter + length) % T::BLOCKSIZE);
  69. }
  70. template <class T>
  71. void DMAC_Base<T>::TruncatedFinal(byte *mac, size_t size)
  72. {
  73. ThrowIfInvalidTruncatedSize(size);
  74. byte pad[T::BLOCKSIZE];
  75. byte padByte = byte(T::BLOCKSIZE-m_counter);
  76. memset(pad, padByte, padByte);
  77. m_mac1.Update(pad, padByte);
  78. m_mac1.TruncatedFinal(mac, size);
  79. m_f2.ProcessBlock(mac);
  80. m_counter = 0; // reset for next message
  81. }
  82. template <class T>
  83. byte *DMAC_Base<T>::GenerateSubKeys(const byte *key, size_t keylength)
  84. {
  85. typename T::Encryption cipher(key, keylength);
  86. memset(m_subkeys, 0, m_subkeys.size());
  87. cipher.ProcessBlock(m_subkeys);
  88. m_subkeys[m_subkeys.size()/2 + T::BLOCKSIZE - 1] = 1;
  89. cipher.ProcessBlock(m_subkeys+m_subkeys.size()/2);
  90. return m_subkeys;
  91. }
  92. NAMESPACE_END
  93. #endif