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,6 +24,7 @@ Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next,
24 offset(0), 24 offset(0),
25 nrounds(0), 25 nrounds(0),
26 use_zero_iv(false), 26 use_zero_iv(false),
  27 + use_specified_iv(false),
27 disable_padding(false) 28 disable_padding(false)
28 { 29 {
29 unsigned int keybits = 8 * key_bytes; 30 unsigned int keybits = 8 * key_bytes;
@@ -66,6 +67,19 @@ Pl_AES_PDF::disablePadding() @@ -66,6 +67,19 @@ Pl_AES_PDF::disablePadding()
66 } 67 }
67 68
68 void 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 Pl_AES_PDF::disableCBC() 83 Pl_AES_PDF::disableCBC()
70 { 84 {
71 this->cbc_mode = false; 85 this->cbc_mode = false;
@@ -150,18 +164,22 @@ Pl_AES_PDF::initializeVector() @@ -150,18 +164,22 @@ Pl_AES_PDF::initializeVector()
150 srandom((int)QUtil::get_current_time() ^ 0xcccc); 164 srandom((int)QUtil::get_current_time() ^ 0xcccc);
151 seeded_random = true; 165 seeded_random = true;
152 } 166 }
153 - if (use_static_iv) 167 + if (use_zero_iv)
154 { 168 {
155 for (unsigned int i = 0; i < this->buf_size; ++i) 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 for (unsigned int i = 0; i < this->buf_size; ++i) 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 else 185 else
@@ -188,12 +206,12 @@ Pl_AES_PDF::flush(bool strip_padding) @@ -188,12 +206,12 @@ Pl_AES_PDF::flush(bool strip_padding)
188 // Set cbc_block to the initialization vector, and if 206 // Set cbc_block to the initialization vector, and if
189 // not zero, write it to the output stream. 207 // not zero, write it to the output stream.
190 initializeVector(); 208 initializeVector();
191 - if (! this->use_zero_iv) 209 + if (! (this->use_zero_iv || this->use_specified_iv))
192 { 210 {
193 getNext()->write(this->cbc_block, this->buf_size); 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 // Initialize vector with zeroes; zero vector was not 216 // Initialize vector with zeroes; zero vector was not
199 // written to the beginning of the input file. 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,6 +31,10 @@ class Pl_AES_PDF: public Pipeline
31 // Disable padding; needed for AESV3 31 // Disable padding; needed for AESV3
32 QPDF_DLL 32 QPDF_DLL
33 void disablePadding(); 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 // For testing only; PDF always uses CBC 39 // For testing only; PDF always uses CBC
36 QPDF_DLL 40 QPDF_DLL
@@ -55,8 +59,10 @@ class Pl_AES_PDF: public Pipeline @@ -55,8 +59,10 @@ class Pl_AES_PDF: public Pipeline
55 unsigned char inbuf[buf_size]; 59 unsigned char inbuf[buf_size];
56 unsigned char outbuf[buf_size]; 60 unsigned char outbuf[buf_size];
57 unsigned char cbc_block[buf_size]; 61 unsigned char cbc_block[buf_size];
  62 + unsigned char specified_iv[buf_size];
58 unsigned int nrounds; 63 unsigned int nrounds;
59 bool use_zero_iv; 64 bool use_zero_iv;
  65 + bool use_specified_iv;
60 bool disable_padding; 66 bool disable_padding;
61 }; 67 };
62 68