PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/mordor/streams/hash.h

http://github.com/mozy/mordor
C Header | 228 lines | 181 code | 40 blank | 7 comment | 0 complexity | eefe6e3b6ee3bca4dd6e2a199123bb23 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #ifndef __MORDOR_HASH_STREAM_H__
  2. #define __MORDOR_HASH_STREAM_H__
  3. // Copyright (c) 2009 - Mozy, Inc.
  4. #include <vector>
  5. #include <openssl/sha.h>
  6. #include <openssl/md5.h>
  7. #include "assert.h"
  8. #include "filter.h"
  9. #include "buffer.h"
  10. #include "hashfwd.h"
  11. namespace Mordor {
  12. class HashStream : public FilterStream
  13. {
  14. public:
  15. typedef boost::shared_ptr<HashStream> ptr;
  16. public:
  17. HashStream(Stream::ptr parent, bool own = true)
  18. : FilterStream(parent, own)
  19. {}
  20. bool supportsSeek() { return false; }
  21. bool supportsTruncate() { return false; }
  22. bool supportsUnread() { return false; }
  23. size_t read(Buffer &buffer, size_t length);
  24. size_t read(void *buffer, size_t length);
  25. size_t write(const Buffer &buffer, size_t length);
  26. size_t write(const void *buffer, size_t length);
  27. long long seek(long long offset, Anchor anchor = BEGIN);
  28. // Returns the hash in *binary*
  29. virtual std::string hash() const;
  30. virtual size_t hashSize() const = 0;
  31. virtual void hash(void *result, size_t length) const = 0;
  32. /// dump variant Hash context into buffer for later resuming
  33. virtual Buffer dumpContext() const = 0;
  34. virtual void reset() = 0;
  35. protected:
  36. virtual void updateHash(const void *buffer, size_t length) = 0;
  37. };
  38. template<HASH_TYPE H> struct HashOps {};
  39. #ifndef OPENSSL_NO_SHA0
  40. template<>
  41. struct HashOps<SHA0>
  42. {
  43. typedef SHA_CTX ctx_type;
  44. static int init(ctx_type *ctx)
  45. { return SHA_Init(ctx); }
  46. static int update(ctx_type *ctx, const void *data, size_t len)
  47. { return SHA_Update(ctx, data, len); }
  48. static int final(unsigned char *md, ctx_type *ctx)
  49. { return SHA_Final(md, ctx); }
  50. static size_t digestLength() { return SHA_DIGEST_LENGTH; }
  51. };
  52. #endif
  53. #ifndef OPENSSL_NO_SHA1
  54. template<>
  55. struct HashOps<SHA1>
  56. {
  57. typedef SHA_CTX ctx_type;
  58. static int init(ctx_type *ctx)
  59. { return SHA1_Init(ctx); }
  60. static int update(ctx_type *ctx, const void *data, size_t len)
  61. { return SHA1_Update(ctx, data, len); }
  62. static int final(unsigned char *md, ctx_type *ctx)
  63. { return SHA1_Final(md, ctx); }
  64. static size_t digestLength() { return SHA_DIGEST_LENGTH; }
  65. };
  66. #endif
  67. #ifndef OPENSSL_NO_SHA256
  68. template<>
  69. struct HashOps<SHA224>
  70. {
  71. typedef SHA256_CTX ctx_type;
  72. static int init(ctx_type *ctx)
  73. { return SHA224_Init(ctx); }
  74. static int update(ctx_type *ctx, const void *data, size_t len)
  75. { return SHA224_Update(ctx, data, len); }
  76. static int final(unsigned char *md, ctx_type *ctx)
  77. { return SHA224_Final(md, ctx); }
  78. static size_t digestLength() { return SHA224_DIGEST_LENGTH; }
  79. };
  80. template<>
  81. struct HashOps<SHA256>
  82. {
  83. typedef SHA256_CTX ctx_type;
  84. static int init(ctx_type *ctx)
  85. { return SHA256_Init(ctx); }
  86. static int update(ctx_type *ctx, const void *data, size_t len)
  87. { return SHA256_Update(ctx, data, len); }
  88. static int final(unsigned char *md, ctx_type *ctx)
  89. { return SHA256_Final(md, ctx); }
  90. static size_t digestLength() { return SHA256_DIGEST_LENGTH; }
  91. };
  92. #endif
  93. template<>
  94. struct HashOps<MD5>
  95. {
  96. typedef MD5_CTX ctx_type;
  97. static int init(ctx_type *ctx)
  98. { return MD5_Init(ctx); }
  99. static int update(ctx_type *ctx, const void *data, size_t len)
  100. { return MD5_Update(ctx, data, len); }
  101. static int final(unsigned char *md, ctx_type *ctx)
  102. { return MD5_Final(md, ctx); }
  103. static size_t digestLength() { return MD5_DIGEST_LENGTH; }
  104. };
  105. template<HASH_TYPE H>
  106. class _HashStream : public HashStream
  107. {
  108. public:
  109. typedef typename HashOps<H>::ctx_type ctx_type;
  110. typedef boost::shared_ptr<_HashStream<H> > ptr;
  111. private:
  112. typedef HashOps<H> hash_ops;
  113. public:
  114. _HashStream(Stream::ptr parent, bool own = true)
  115. : HashStream(parent, own)
  116. { hash_ops::init(&m_ctx); }
  117. _HashStream(Stream::ptr parent, const ctx_type &ctx, bool own = true)
  118. : HashStream(parent, own)
  119. , m_ctx(ctx)
  120. {}
  121. _HashStream(Stream::ptr parent, const Buffer &buffer, bool own = true)
  122. : HashStream(parent, own)
  123. { buffer.copyOut(&m_ctx, sizeof(ctx_type)); }
  124. size_t hashSize() const { return hash_ops::digestLength(); }
  125. void reset() { hash_ops::init(&m_ctx); }
  126. ctx_type ctx() const { return m_ctx; }
  127. using HashStream::hash;
  128. void hash(void *result, size_t length) const
  129. {
  130. ctx_type copy(m_ctx);
  131. hash_ops::final((unsigned char *)result, &copy);
  132. }
  133. Buffer dumpContext() const
  134. {
  135. Buffer buffer;
  136. buffer.copyIn(&m_ctx, sizeof(ctx_type));
  137. return buffer;
  138. }
  139. private:
  140. void updateHash(const void *buffer, size_t length)
  141. { hash_ops::update(&m_ctx, buffer, length); }
  142. protected:
  143. ctx_type m_ctx;
  144. };
  145. #ifndef OPENSSL_NO_SHA0
  146. typedef _HashStream<SHA0> SHA0Stream;
  147. #endif
  148. #ifndef OPENSSL_NO_SHA1
  149. typedef _HashStream<SHA1> SHA1Stream;
  150. #endif
  151. #ifndef OPENSSL_NO_SHA256
  152. typedef _HashStream<SHA224> SHA224Stream;
  153. typedef _HashStream<SHA256> SHA256Stream;
  154. #endif
  155. typedef _HashStream<MD5> MD5Stream;
  156. class CRC32Stream : public HashStream
  157. {
  158. public:
  159. /// Using a well-known polynomial will automatically select a precomputed table
  160. enum WellknownPolynomial
  161. {
  162. /// CRC-32-IEEE, used in V.42, Ethernet, MPEG-2, PNG, POSIX cksum, etc.
  163. IEEE = 0x04C11DB7,
  164. /// CRC-32C used in iSCSI and SCTP
  165. CASTAGNOLI = 0x1EDC6F41,
  166. /// CRC-32K
  167. KOOPMAN = 0x741B8CD7
  168. };
  169. public:
  170. CRC32Stream(Stream::ptr parent, unsigned int polynomial = IEEE,
  171. bool own = true);
  172. CRC32Stream(Stream::ptr parent, const unsigned int *precomputedTable,
  173. bool own = true);
  174. static std::vector<unsigned int> precomputeTable(unsigned int polynomial);
  175. size_t hashSize() const;
  176. using HashStream::hash;
  177. void hash(void *result, size_t length) const;
  178. void reset();
  179. Buffer dumpContext() const { return Buffer(); }
  180. protected:
  181. void updateHash(const void *buffer, size_t length);
  182. private:
  183. unsigned int m_crc;
  184. const std::vector<unsigned int> m_tableStorage;
  185. const unsigned int *m_table;
  186. };
  187. }
  188. #endif