From 3680922ae5efbf544afcfa3dd72e2f1db336c45f Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 29 Dec 2012 10:43:46 -0500 Subject: Allow specification of AES initialization vector --- libqpdf/Pl_AES_PDF.cc | 30 ++++++++++++++++++++++++------ libqpdf/qpdf/Pl_AES_PDF.hh | 6 ++++++ 2 files changed, 30 insertions(+), 6 deletions(-) (limited to 'libqpdf') diff --git a/libqpdf/Pl_AES_PDF.cc b/libqpdf/Pl_AES_PDF.cc index 57bf5766..09c975d6 100644 --- a/libqpdf/Pl_AES_PDF.cc +++ b/libqpdf/Pl_AES_PDF.cc @@ -24,6 +24,7 @@ Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next, offset(0), nrounds(0), use_zero_iv(false), + use_specified_iv(false), disable_padding(false) { unsigned int keybits = 8 * key_bytes; @@ -65,6 +66,19 @@ Pl_AES_PDF::disablePadding() this->disable_padding = true; } +void +Pl_AES_PDF::setIV(unsigned char const* iv, size_t bytes) +{ + if (bytes != this->buf_size) + { + throw std::logic_error( + "Pl_AES_PDF: specified initialization vector" + " size in bytes must be " + QUtil::int_to_string(bytes)); + } + this->use_specified_iv = true; + memcpy(this->specified_iv, iv, bytes); +} + void Pl_AES_PDF::disableCBC() { @@ -150,18 +164,22 @@ Pl_AES_PDF::initializeVector() srandom((int)QUtil::get_current_time() ^ 0xcccc); seeded_random = true; } - if (use_static_iv) + if (use_zero_iv) { for (unsigned int i = 0; i < this->buf_size; ++i) { - this->cbc_block[i] = 14 * (1 + i); + this->cbc_block[i] = 0; } } - else if (use_zero_iv) + else if (use_specified_iv) + { + std::memcpy(this->cbc_block, this->specified_iv, this->buf_size); + } + else if (use_static_iv) { for (unsigned int i = 0; i < this->buf_size; ++i) { - this->cbc_block[i] = 0; + this->cbc_block[i] = 14 * (1 + i); } } else @@ -188,12 +206,12 @@ Pl_AES_PDF::flush(bool strip_padding) // Set cbc_block to the initialization vector, and if // not zero, write it to the output stream. initializeVector(); - if (! this->use_zero_iv) + if (! (this->use_zero_iv || this->use_specified_iv)) { getNext()->write(this->cbc_block, this->buf_size); } } - else if (this->use_zero_iv) + else if (this->use_zero_iv || this->use_specified_iv) { // Initialize vector with zeroes; zero vector was not // written to the beginning of the input file. diff --git a/libqpdf/qpdf/Pl_AES_PDF.hh b/libqpdf/qpdf/Pl_AES_PDF.hh index 72f82229..9aa73ad6 100644 --- a/libqpdf/qpdf/Pl_AES_PDF.hh +++ b/libqpdf/qpdf/Pl_AES_PDF.hh @@ -31,6 +31,10 @@ class Pl_AES_PDF: public Pipeline // Disable padding; needed for AESV3 QPDF_DLL void disablePadding(); + // Specify an initialization vector, which will not be included in + // the output. + QPDF_DLL + void setIV(unsigned char const* iv, size_t bytes); // For testing only; PDF always uses CBC QPDF_DLL @@ -55,8 +59,10 @@ class Pl_AES_PDF: public Pipeline unsigned char inbuf[buf_size]; unsigned char outbuf[buf_size]; unsigned char cbc_block[buf_size]; + unsigned char specified_iv[buf_size]; unsigned int nrounds; bool use_zero_iv; + bool use_specified_iv; bool disable_padding; }; -- cgit v1.2.3-54-g00ecf