Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.5 KiB

  1. #ifndef CRYPTOPP_DMAC_H
  2. #define CRYPTOPP_DMAC_H
  3. #include "cbcmac.h"
  4. NAMESPACE_BEGIN(CryptoPP)
  5. //! _
  6. template <class T>
  7. class CRYPTOPP_NO_VTABLE DMAC_Base : public SameKeyLengthAs<T>, public MessageAuthenticationCode
  8. {
  9. public:
  10. static std::string StaticAlgorithmName() {return std::string("DMAC(") + T::StaticAlgorithmName() + ")";}
  11. CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE)
  12. DMAC_Base() {}
  13. void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
  14. void Update(const byte *input, size_t length);
  15. void TruncatedFinal(byte *mac, size_t size);
  16. unsigned int DigestSize() const {return DIGESTSIZE;}
  17. private:
  18. byte *GenerateSubKeys(const byte *key, size_t keylength);
  19. size_t m_subkeylength;
  20. SecByteBlock m_subkeys;
  21. CBC_MAC<T> m_mac1;
  22. typename T::Encryption m_f2;
  23. unsigned int m_counter;
  24. };
  25. //! DMAC
  26. /*! Based on "CBC MAC for Real-Time Data Sources" by Erez Petrank
  27. and Charles Rackoff. T should be a class derived from BlockCipherDocumentation.
  28. */
  29. template <class T>
  30. class DMAC : public MessageAuthenticationCodeFinal<DMAC_Base<T> >
  31. {
  32. public:
  33. DMAC() {}
  34. DMAC(const byte *key, size_t length=DMAC_Base<T>::DEFAULT_KEYLENGTH)
  35. {this->SetKey(key, length);}
  36. };
  37. template <class T>
  38. void DMAC_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
  39. {
  40. m_subkeylength = T::StaticGetValidKeyLength(T::BLOCKSIZE);
  41. m_subkeys.resize(2*UnsignedMin((unsigned int)T::BLOCKSIZE, m_subkeylength));
  42. m_mac1.SetKey(GenerateSubKeys(key, length), m_subkeylength, params);
  43. m_f2.SetKey(m_subkeys+m_subkeys.size()/2, m_subkeylength, params);
  44. m_counter = 0;
  45. m_subkeys.resize(0);
  46. }
  47. template <class T>
  48. void DMAC_Base<T>::Update(const byte *input, size_t length)
  49. {
  50. m_mac1.Update(input, length);
  51. m_counter = (unsigned int)((m_counter + length) % T::BLOCKSIZE);
  52. }
  53. template <class T>
  54. void DMAC_Base<T>::TruncatedFinal(byte *mac, size_t size)
  55. {
  56. ThrowIfInvalidTruncatedSize(size);
  57. byte pad[T::BLOCKSIZE];
  58. byte padByte = byte(T::BLOCKSIZE-m_counter);
  59. memset(pad, padByte, padByte);
  60. m_mac1.Update(pad, padByte);
  61. m_mac1.TruncatedFinal(mac, size);
  62. m_f2.ProcessBlock(mac);
  63. m_counter = 0; // reset for next message
  64. }
  65. template <class T>
  66. byte *DMAC_Base<T>::GenerateSubKeys(const byte *key, size_t keylength)
  67. {
  68. typename T::Encryption cipher(key, keylength);
  69. memset(m_subkeys, 0, m_subkeys.size());
  70. cipher.ProcessBlock(m_subkeys);
  71. m_subkeys[m_subkeys.size()/2 + T::BLOCKSIZE - 1] = 1;
  72. cipher.ProcessBlock(m_subkeys+m_subkeys.size()/2);
  73. return m_subkeys;
  74. }
  75. NAMESPACE_END
  76. #endif