Line | Count | Source (jump to first uncovered line) |
1 | | // mdc.h - originally written and placed in the public domain by Wei Dai |
2 | | |
3 | | /// \file mdc.h |
4 | | /// \brief Classes for the MDC message digest |
5 | | |
6 | | #ifndef CRYPTOPP_MDC_H |
7 | | #define CRYPTOPP_MDC_H |
8 | | |
9 | | #include "seckey.h" |
10 | | #include "secblock.h" |
11 | | #include "misc.h" |
12 | | |
13 | | // GCC cast warning |
14 | 0 | #define HashWordPtr(x) ((HashWordType*)(void*)(x)) |
15 | 0 | #define ConstHashWordPtr(x) ((const HashWordType*)(const void*)(x)) |
16 | | |
17 | | NAMESPACE_BEGIN(CryptoPP) |
18 | | |
19 | | /// \tparam B BlockCipher derived class |
20 | | /// \brief MDC_Info cipher information |
21 | | template <class B> |
22 | | struct MDC_Info : public FixedBlockSize<B::DIGESTSIZE>, public FixedKeyLength<B::BLOCKSIZE> |
23 | | { |
24 | 0 | static std::string StaticAlgorithmName() {return std::string("MDC/")+B::StaticAlgorithmName();} |
25 | | }; |
26 | | |
27 | | /// \brief MDC cipher |
28 | | /// \tparam H HashTransformation derived class |
29 | | /// \details MDC() is a construction by Peter Gutmann to turn an iterated hash function into a PRF |
30 | | /// \sa <a href="http://www.cryptopp.com/wiki/MDC">MDC</a> |
31 | | template <class H> |
32 | | class MDC : public MDC_Info<H> |
33 | | { |
34 | | /// \brief MDC cipher encryption operation |
35 | | class CRYPTOPP_NO_VTABLE Enc : public BlockCipherImpl<MDC_Info<H> > |
36 | | { |
37 | | typedef typename H::HashWordType HashWordType; |
38 | | |
39 | | public: |
40 | | void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) |
41 | 0 | { |
42 | 0 | CRYPTOPP_UNUSED(params); |
43 | 0 | this->AssertValidKeyLength(length); |
44 | 0 | ConditionalByteReverse(BIG_ENDIAN_ORDER, Key(), ConstHashWordPtr(userKey), this->KEYLENGTH); |
45 | 0 | } |
46 | | |
47 | | void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const |
48 | 0 | { |
49 | 0 | ConditionalByteReverse(BIG_ENDIAN_ORDER, Buffer(), ConstHashWordPtr(inBlock), this->BLOCKSIZE); |
50 | 0 | H::Transform(Buffer(), Key()); |
51 | |
|
52 | 0 | if (xorBlock) |
53 | 0 | { |
54 | 0 | ConditionalByteReverse(BIG_ENDIAN_ORDER, Buffer(), Buffer(), this->BLOCKSIZE); |
55 | 0 | xorbuf(outBlock, xorBlock, m_buffer, this->BLOCKSIZE); |
56 | 0 | } |
57 | 0 | else |
58 | 0 | { |
59 | 0 | ConditionalByteReverse(BIG_ENDIAN_ORDER, HashWordPtr(outBlock), Buffer(), this->BLOCKSIZE); |
60 | 0 | } |
61 | 0 | } |
62 | | |
63 | 0 | bool IsPermutation() const {return false;} |
64 | | |
65 | 0 | unsigned int OptimalDataAlignment() const {return sizeof(HashWordType);} |
66 | | |
67 | | private: |
68 | 0 | HashWordType *Key() {return HashWordPtr(m_key.data());} |
69 | 0 | const HashWordType *Key() const {return ConstHashWordPtr(m_key.data());} |
70 | 0 | HashWordType *Buffer() const {return HashWordPtr(m_buffer.data());} |
71 | | |
72 | | // VC60 workaround: bug triggered if using FixedSizeAllocatorWithCleanup |
73 | | FixedSizeSecBlock<byte, MDC_Info<H>::KEYLENGTH, AllocatorWithCleanup<byte> > m_key; |
74 | | mutable FixedSizeSecBlock<byte, MDC_Info<H>::BLOCKSIZE, AllocatorWithCleanup<byte> > m_buffer; |
75 | | }; |
76 | | |
77 | | public: |
78 | | // use BlockCipher interface |
79 | | typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; |
80 | | }; |
81 | | |
82 | | NAMESPACE_END |
83 | | |
84 | | #endif |