summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2012-12-29 16:43:46 +0100
committerJay Berkenbilt <ejb@ql.org>2012-12-31 11:36:50 +0100
commit3680922ae5efbf544afcfa3dd72e2f1db336c45f (patch)
treedf0e45261d1b70de9d4e9e807a6a6b507d0a5200
parent9b42f526dffd5e1518ff3d83564eb09111ac5f0d (diff)
downloadqpdf-3680922ae5efbf544afcfa3dd72e2f1db336c45f.tar.zst
Allow specification of AES initialization vector
-rw-r--r--libqpdf/Pl_AES_PDF.cc30
-rw-r--r--libqpdf/qpdf/Pl_AES_PDF.hh6
2 files changed, 30 insertions, 6 deletions
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;
@@ -66,6 +67,19 @@ Pl_AES_PDF::disablePadding()
}
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()
{
this->cbc_mode = false;
@@ -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;
};