PageRenderTime 13ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/mordor/streams/crypto.h

http://github.com/mozy/mordor
C Header | 82 lines | 51 code | 13 blank | 18 comment | 2 complexity | cb0c3e3bdcd65e6a404e9002f3806788 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #ifndef __MORDOR_CRYPTO_STREAM__
  2. #define __MORDOR_CRYPTO_STREAM__
  3. // Copyright (c) 2011 - Mozy, Inc.
  4. #include <openssl/evp.h>
  5. #include "filter.h"
  6. #include "buffer.h"
  7. namespace Mordor {
  8. // encryption/decryption stream using OpenSSL EVP API
  9. // supports all four permutations of (encrypt, decrypt) and (read, write),
  10. // although only one per instance
  11. // NOTE: if WRITE, close() must be called when finish!!!
  12. class CryptoStream : public MutatingFilterStream
  13. {
  14. public:
  15. typedef boost::shared_ptr<CryptoStream> ptr;
  16. static const std::string RANDOM_IV;
  17. enum Direction {
  18. INFER, // check whether parent supportsRead() or supportsWrite();
  19. // exactly one of these must be true
  20. READ,
  21. WRITE
  22. };
  23. enum Operation {
  24. AUTO, // encrypt on WRITE; decrypt on READ
  25. DECRYPT,
  26. ENCRYPT
  27. };
  28. // cipher is e.g. EVP_aes_256_cbc() (see openssl/evp.h for all options)
  29. // key and iv are *binary* and must be the correct length for the cipher
  30. // if iv is required and not supplied (or set to RANDOM_IV),
  31. // then the initialization vector will:
  32. // * on encrypt, generated randomly and prepended to the ciphertext
  33. // * on decrypt, extracted from the beginning of the ciphertext
  34. // WARNING: due to older versions of OpenSSL reporting a nonzero IV size
  35. // for ECB cipher contexts, you should explicitly supply an empty IV
  36. // instead of RANDOM_IV when operating in ECB mode
  37. // WARNING: using RANDOM_IV will cause the generated cipher data incompatible
  38. // with openssl tool implementation, hence no 3rdparty tool can decrypt the
  39. // cipher data directly except Mordor::CryptoStream itself
  40. CryptoStream(Stream::ptr parent, const EVP_CIPHER *cipher, const std::string &key,
  41. const std::string &iv = RANDOM_IV, Direction = INFER, Operation = AUTO,
  42. bool own = true);
  43. ~CryptoStream();
  44. bool supportsRead() { return m_dir == READ; }
  45. bool supportsWrite() { return m_dir == WRITE; }
  46. bool supportsSeek() { return false; }
  47. bool supportsSize() { return false; }
  48. void close(CloseType type = BOTH);
  49. using MutatingFilterStream::read;
  50. size_t read(Buffer &buffer, size_t len);
  51. using MutatingFilterStream::write;
  52. size_t write(const Buffer &buffer, size_t len);
  53. private:
  54. size_t cipher(const Buffer &src, Buffer &dst, size_t len, size_t skip = 0); // ciphers len bytes from src
  55. size_t final(Buffer &dst); // finalizes the cipher and writes the last few bytes to dst
  56. void write_buffer(Buffer &buffer); // writes and consumes entire buffer
  57. void init_iv();
  58. void finalize();
  59. std::string m_iv;
  60. Direction m_dir;
  61. Operation m_op;
  62. Buffer m_buf, m_tmp;
  63. EVP_CIPHER_CTX m_ctx;
  64. int m_blocksize;
  65. bool m_eof;
  66. size_t m_iv_to_extract;
  67. };
  68. }
  69. #endif