Commit 3680922ae5efbf544afcfa3dd72e2f1db336c45f

Authored by Jay Berkenbilt
1 parent 9b42f526

Allow specification of AES initialization vector

libqpdf/Pl_AES_PDF.cc
... ... @@ -24,6 +24,7 @@ Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next,
24 24 offset(0),
25 25 nrounds(0),
26 26 use_zero_iv(false),
  27 + use_specified_iv(false),
27 28 disable_padding(false)
28 29 {
29 30 unsigned int keybits = 8 * key_bytes;
... ... @@ -66,6 +67,19 @@ Pl_AES_PDF::disablePadding()
66 67 }
67 68  
68 69 void
  70 +Pl_AES_PDF::setIV(unsigned char const* iv, size_t bytes)
  71 +{
  72 + if (bytes != this->buf_size)
  73 + {
  74 + throw std::logic_error(
  75 + "Pl_AES_PDF: specified initialization vector"
  76 + " size in bytes must be " + QUtil::int_to_string(bytes));
  77 + }
  78 + this->use_specified_iv = true;
  79 + memcpy(this->specified_iv, iv, bytes);
  80 +}
  81 +
  82 +void
69 83 Pl_AES_PDF::disableCBC()
70 84 {
71 85 this->cbc_mode = false;
... ... @@ -150,18 +164,22 @@ Pl_AES_PDF::initializeVector()
150 164 srandom((int)QUtil::get_current_time() ^ 0xcccc);
151 165 seeded_random = true;
152 166 }
153   - if (use_static_iv)
  167 + if (use_zero_iv)
154 168 {
155 169 for (unsigned int i = 0; i < this->buf_size; ++i)
156 170 {
157   - this->cbc_block[i] = 14 * (1 + i);
  171 + this->cbc_block[i] = 0;
158 172 }
159 173 }
160   - else if (use_zero_iv)
  174 + else if (use_specified_iv)
  175 + {
  176 + std::memcpy(this->cbc_block, this->specified_iv, this->buf_size);
  177 + }
  178 + else if (use_static_iv)
161 179 {
162 180 for (unsigned int i = 0; i < this->buf_size; ++i)
163 181 {
164   - this->cbc_block[i] = 0;
  182 + this->cbc_block[i] = 14 * (1 + i);
165 183 }
166 184 }
167 185 else
... ... @@ -188,12 +206,12 @@ Pl_AES_PDF::flush(bool strip_padding)
188 206 // Set cbc_block to the initialization vector, and if
189 207 // not zero, write it to the output stream.
190 208 initializeVector();
191   - if (! this->use_zero_iv)
  209 + if (! (this->use_zero_iv || this->use_specified_iv))
192 210 {
193 211 getNext()->write(this->cbc_block, this->buf_size);
194 212 }
195 213 }
196   - else if (this->use_zero_iv)
  214 + else if (this->use_zero_iv || this->use_specified_iv)
197 215 {
198 216 // Initialize vector with zeroes; zero vector was not
199 217 // written to the beginning of the input file.
... ...
libqpdf/qpdf/Pl_AES_PDF.hh
... ... @@ -31,6 +31,10 @@ class Pl_AES_PDF: public Pipeline
31 31 // Disable padding; needed for AESV3
32 32 QPDF_DLL
33 33 void disablePadding();
  34 + // Specify an initialization vector, which will not be included in
  35 + // the output.
  36 + QPDF_DLL
  37 + void setIV(unsigned char const* iv, size_t bytes);
34 38  
35 39 // For testing only; PDF always uses CBC
36 40 QPDF_DLL
... ... @@ -55,8 +59,10 @@ class Pl_AES_PDF: public Pipeline
55 59 unsigned char inbuf[buf_size];
56 60 unsigned char outbuf[buf_size];
57 61 unsigned char cbc_block[buf_size];
  62 + unsigned char specified_iv[buf_size];
58 63 unsigned int nrounds;
59 64 bool use_zero_iv;
  65 + bool use_specified_iv;
60 66 bool disable_padding;
61 67 };
62 68  
... ...