MagickCore  6.9.13-7
Convert, Edit, Or Compose Bitmap Images
cipher.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % CCCC IIIII PPPP H H EEEEE RRRR %
6 % C I P P H H E R R %
7 % C I PPPP HHHHH EEE RRRR %
8 % C I P H H E R R %
9 % CCCC IIIII P H H EEEEE R R %
10 % %
11 % %
12 % MagickCore Cipher Methods %
13 % %
14 % Software Design %
15 % Cristy %
16 % March 2003 %
17 % %
18 % %
19 % Copyright 1999 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
21 % %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
24 % %
25 % https://imagemagick.org/script/license.php %
26 % %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
32 % %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 %
36 */
37 ␌
38 /*
39  Include declarations.
40 */
41 #include "magick/studio.h"
42 #include "magick/cache.h"
43 #include "magick/cipher.h"
44 #include "magick/exception.h"
45 #include "magick/exception-private.h"
46 #include "magick/hashmap.h"
47 #include "magick/image.h"
48 #include "magick/image-private.h"
49 #include "magick/list.h"
50 #include "magick/memory_.h"
51 #include "magick/monitor.h"
52 #include "magick/monitor-private.h"
53 #include "magick/property.h"
54 #include "magick/quantum-private.h"
55 #include "magick/registry.h"
56 #include "magick/semaphore.h"
57 #include "magick/signature-private.h"
58 #include "magick/splay-tree.h"
59 #include "magick/statistic.h"
60 #include "magick/string_.h"
61 #include "magick/timer-private.h"
62 ␌
63 #if defined(MAGICKCORE_CIPHER_SUPPORT)
64 /*
65  Define declarations.
66 */
67 #define AESBlocksize 16
68 ␌
69 /*
70  Typedef declarations.
71 */
72 typedef struct _AESInfo
73 {
75  *key;
76 
77  unsigned int
78  blocksize,
79  *encipher_key,
80  *decipher_key;
81 
82  ssize_t
83  rounds;
84 
85  time_t
86  timestamp;
87 
88  size_t
89  signature;
90 } AESInfo;
91 ␌
92 /*
93  Global declarations.
94 */
95 static unsigned char
96  InverseLog[256] =
97  {
98  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248,
99  19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10,
100  30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190,
101  217, 112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204,
102  79, 209, 104, 184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59,
103  77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208,
104  107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196,
105  87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
106  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32,
107  96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86,
108  250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237,
109  44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126,
110  130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35,
111  101, 175, 234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99,
112  165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, 69, 207,
113  74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
114  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242,
115  13, 23, 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180,
116  199, 82, 246, 1
117  },
118  Log[256] =
119  {
120  0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238,
121  223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200,
122  248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228,
123  166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36,
124  18, 240, 130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208,
125  206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253, 48,
126  191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110,
127  72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
128  43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115,
129  167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213,
130  231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245, 89, 203,
131  95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236,
132  216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96,
133  177, 134, 59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144,
134  97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, 83, 57,
135  132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
136  68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153,
137  227, 165, 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128,
138  192, 247, 112, 7,
139  },
140  SBox[256] =
141  {
142  99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215,
143  171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175,
144  156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
145  229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154,
146  7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
147  90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237,
148  32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239,
149  170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
150  81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255,
151  243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
152  100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238,
153  184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92,
154  194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213,
155  78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46,
156  28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
157  181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
158  225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85,
159  40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15,
160  176, 84, 187, 22
161  };
162 ␌
163 /*
164  Forward declarations.
165 */
166 static AESInfo
167  *DestroyAESInfo(AESInfo *);
168 
169 static void
170  EncipherAESBlock(AESInfo *,const unsigned char *,unsigned char *),
171  SetAESKey(AESInfo *,const StringInfo *);
172 ␌
173 /*
174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175 % %
176 % %
177 % %
178 % A c q u i r e A E S I n f o %
179 % %
180 % %
181 % %
182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183 %
184 % AcquireAESInfo() allocate the AESInfo structure.
185 %
186 % The format of the AcquireAESInfo method is:
187 %
188 % AESInfo *AcquireAESInfo(void)
189 %
190 */
191 static AESInfo *AcquireAESInfo(void)
192 {
193  AESInfo
194  *aes_info;
195 
196  aes_info=(AESInfo *) AcquireMagickMemory(sizeof(*aes_info));
197  if (aes_info == (AESInfo *) NULL)
198  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
199  (void) memset(aes_info,0,sizeof(*aes_info));
200  aes_info->blocksize=AESBlocksize;
201  aes_info->key=AcquireStringInfo(32);
202  aes_info->encipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
203  *aes_info->encipher_key));
204  aes_info->decipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
205  *aes_info->decipher_key));
206  if ((aes_info->key == (StringInfo *) NULL) ||
207  (aes_info->encipher_key == (unsigned int *) NULL) ||
208  (aes_info->decipher_key == (unsigned int *) NULL))
209  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
210  aes_info->timestamp=GetMagickTime();
211  aes_info->signature=MagickCoreSignature;
212  return(aes_info);
213 }
214 ␌
215 /*
216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217 % %
218 % %
219 % %
220 % D e s t r o y A E S I n f o %
221 % %
222 % %
223 % %
224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
225 %
226 % DestroyAESInfo() zeros memory associated with the AESInfo structure.
227 %
228 % The format of the DestroyAESInfo method is:
229 %
230 % AESInfo *DestroyAESInfo(AESInfo *aes_info)
231 %
232 % A description of each parameter follows:
233 %
234 % o aes_info: the cipher context.
235 %
236 */
237 static AESInfo *DestroyAESInfo(AESInfo *aes_info)
238 {
239  assert(aes_info != (AESInfo *) NULL);
240  assert(aes_info->signature == MagickCoreSignature);
241  if (IsEventLogging() != MagickFalse)
242  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
243  if (aes_info->decipher_key != (unsigned int *) NULL)
244  aes_info->decipher_key=(unsigned int *) RelinquishMagickMemory(
245  aes_info->decipher_key);
246  if (aes_info->encipher_key != (unsigned int *) NULL)
247  aes_info->encipher_key=(unsigned int *) RelinquishMagickMemory(
248  aes_info->encipher_key);
249  if (aes_info->key != (StringInfo *) NULL)
250  aes_info->key=DestroyStringInfo(aes_info->key);
251  aes_info->signature=(~MagickCoreSignature);
252  aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
253  return(aes_info);
254 }
255 ␌
256 /*
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 % %
259 % %
260 % %
261 % E n c i p h e r A E S B l o c k %
262 % %
263 % %
264 % %
265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 %
267 % EncipherAESBlock() enciphers a single block of plaintext to produce a block
268 % of ciphertext.
269 %
270 % The format of the EncipherAESBlock method is:
271 %
272 % void EncipherAES(AESInfo *aes_info,const unsigned char *plaintext,
273 % unsigned char *ciphertext)
274 %
275 % A description of each parameter follows:
276 %
277 % o aes_info: the cipher context.
278 %
279 % o plaintext: the plain text.
280 %
281 % o ciphertext: the cipher text.
282 %
283 */
284 
285 static inline void AddRoundKey(const unsigned int *ciphertext,
286  const unsigned int *key,unsigned int *plaintext)
287 {
288  ssize_t
289  i;
290 
291  /*
292  Xor corresponding text input and round key input bytes.
293  */
294  for (i=0; i < 4; i++)
295  plaintext[i]=key[i] ^ ciphertext[i];
296 }
297 
298 static inline unsigned int ByteMultiply(const unsigned char alpha,
299  const unsigned char beta)
300 {
301  /*
302  Byte multiply two elements of GF(2^m) (mix columns and inverse mix columns).
303  */
304  if ((alpha == 0) || (beta == 0))
305  return(0);
306  return((unsigned int) InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
307 }
308 
309 static inline unsigned int ByteSubTransform(unsigned int x,
310  unsigned char *s_box)
311 {
312  unsigned int
313  key;
314 
315  /*
316  Non-linear layer resists differential and linear cryptoanalysis attacks.
317  */
318  key=((unsigned int) s_box[x & 0xff]) |
319  ((unsigned int) s_box[(x >> 8) & 0xff] << 8) |
320  ((unsigned int) s_box[(x >> 16) & 0xff] << 16) |
321  ((unsigned int) s_box[(x >> 24) & 0xff] << 24);
322  return(key);
323 }
324 
325 static void FinalizeRoundKey(const unsigned int *ciphertext,
326  const unsigned int *key,unsigned char *plaintext)
327 {
328  unsigned char
329  *p;
330 
331  unsigned int
332  i,
333  j;
334 
335  unsigned int
336  value;
337 
338  /*
339  The round key is XORed with the result of the mix-column transformation.
340  */
341  p=plaintext;
342  for (i=0; i < 4; i++)
343  {
344  value=ciphertext[i] ^ key[i];
345  for (j=0; j < 4; j++)
346  *p++=(unsigned char) ((value >> (8*j)) & 0xff);
347  }
348  /*
349  Reset registers.
350  */
351  value=0;
352 }
353 
354 static void InitializeRoundKey(const unsigned char *ciphertext,
355  const unsigned int *key,unsigned int *plaintext)
356 {
357  const unsigned char
358  *p;
359 
360  unsigned int
361  i,
362  j;
363 
364  unsigned int
365  value;
366 
367  p=ciphertext;
368  for (i=0; i < 4; i++)
369  {
370  value=0;
371  for (j=0; j < 4; j++)
372  value|=((unsigned int) *p++ << (8*j));
373  plaintext[i]=key[i] ^ value;
374  }
375  /*
376  Reset registers.
377  */
378  value=0;
379 }
380 
381 static inline unsigned int RotateLeft(const unsigned int x)
382 {
383  return(((x << 8) | ((x >> 24) & 0xff)));
384 }
385 
386 static void EncipherAESBlock(AESInfo *aes_info,const unsigned char *plaintext,
387  unsigned char *ciphertext)
388 {
389  ssize_t
390  i,
391  j;
392 
393  static int
394  map[4][4] =
395  {
396  { 0, 1, 2, 3 },
397  { 1, 2, 3, 0 },
398  { 2, 3, 0, 1 },
399  { 3, 0, 1, 2 }
400  };
401 
402  static unsigned int
403  D[] =
404  {
405  0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
406  0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
407  0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
408  0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
409  0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
410  0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
411  0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
412  0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
413  0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
414  0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
415  0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
416  0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
417  0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
418  0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
419  0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
420  0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
421  0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
422  0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
423  0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
424  0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
425  0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
426  0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
427  0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
428  0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
429  0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
430  0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
431  0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
432  0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
433  0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
434  0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
435  0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
436  0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
437  0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
438  0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
439  0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
440  0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
441  0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
442  0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
443  0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
444  0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
445  0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
446  0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
447  0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
448  0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
449  0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
450  0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
451  0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
452  0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
453  0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
454  0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
455  0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
456  0x3a16162cU
457  };
458 
459  unsigned int
460  alpha,
461  key[4],
462  text[4];
463 
464  /*
465  Encipher one block.
466  */
467  (void) memset(text,0,sizeof(text));
468  InitializeRoundKey(plaintext,aes_info->encipher_key,text);
469  for (i=1; i < aes_info->rounds; i++)
470  {
471  /*
472  Linear mixing step: cause diffusion of the bits over multiple rounds.
473  */
474  for (j=0; j < 4; j++)
475  key[j]=D[text[j] & 0xff] ^
476  RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
477  RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
478  RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
479  AddRoundKey(key,aes_info->encipher_key+4*i,text);
480  }
481  for (i=0; i < 4; i++)
482  {
483  alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
484  ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
485  key[i]=ByteSubTransform(alpha,SBox);
486  }
487  FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
488  /*
489  Reset registers.
490  */
491  alpha=0;
492  (void) ResetMagickMemory(key,0,sizeof(key));
493  (void) ResetMagickMemory(text,0,sizeof(text));
494 }
495 ␌
496 /*
497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
498 % %
499 % %
500 % %
501 % P a s s k e y D e c i p h e r I m a g e %
502 % %
503 % %
504 % %
505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
506 %
507 % PasskeyDecipherImage() converts cipher pixels to plain pixels.
508 %
509 % The format of the PasskeyDecipherImage method is:
510 %
511 % MagickBooleanType PasskeyDecipherImage(Image *image,
512 % const StringInfo *passkey,ExceptionInfo *exception)
513 % MagickBooleanType DecipherImage(Image *image,const char *passphrase,
514 % ExceptionInfo *exception)
515 %
516 % A description of each parameter follows:
517 %
518 % o image: the image.
519 %
520 % o passphrase: decipher cipher pixels with this passphrase.
521 %
522 % o passkey: decrypt cipher pixels with this passkey.
523 %
524 % o exception: return any errors or warnings in this structure.
525 %
526 */
527 
528 static inline void IncrementCipherNonce(const size_t length,
529  unsigned char *nonce)
530 {
531  ssize_t
532  i;
533 
534  for (i=(ssize_t) (length-1); i >= 0; i--)
535  {
536  nonce[i]++;
537  if (nonce[i] != 0)
538  return;
539  }
540  ThrowFatalException(ResourceLimitFatalError,"Sequence wrap error `%s'");
541 }
542 
543 MagickExport MagickBooleanType DecipherImage(Image *image,
544  const char *passphrase,ExceptionInfo *exception)
545 {
546  MagickBooleanType
547  status;
548 
549  StringInfo
550  *passkey;
551 
552  if (passphrase == (const char *) NULL)
553  return(MagickTrue);
554  passkey=StringToStringInfo(passphrase);
555  if (passkey == (StringInfo *) NULL)
556  return(MagickFalse);
557  status=PasskeyDecipherImage(image,passkey,exception);
558  passkey=DestroyStringInfo(passkey);
559  return(status);
560 }
561 
562 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
563  const StringInfo *passkey,ExceptionInfo *exception)
564 {
565 #define DecipherImageTag "Decipher/Image "
566 
567  AESInfo
568  *aes_info;
569 
570  CacheView
571  *image_view;
572 
573  const unsigned char
574  *digest;
575 
576  MagickBooleanType
577  proceed;
578 
579  MagickSizeType
580  extent;
581 
583  *quantum_info;
584 
585  QuantumType
586  quantum_type;
587 
589  *signature_info;
590 
591  unsigned char
592  *p;
593 
594  size_t
595  length;
596 
597  ssize_t
598  y;
599 
600  StringInfo
601  *key,
602  *nonce;
603 
604  unsigned char
605  input_block[AESBlocksize],
606  output_block[AESBlocksize],
607  *pixels;
608 
609  /*
610  Generate decipher key and nonce.
611  */
612  assert(image != (Image *) NULL);
613  assert(image->signature == MagickCoreSignature);
614  assert(exception != (ExceptionInfo *) NULL);
615  assert(exception->signature == MagickCoreSignature);
616  if (IsEventLogging() != MagickFalse)
617  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
618  if (passkey == (const StringInfo *) NULL)
619  return(MagickTrue);
620  aes_info=AcquireAESInfo();
621  key=CloneStringInfo(passkey);
622  if (key == (StringInfo *) NULL)
623  {
624  aes_info=DestroyAESInfo(aes_info);
625  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
626  image->filename);
627  }
628  nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
629  if (nonce == (StringInfo *) NULL)
630  {
631  key=DestroyStringInfo(key);
632  aes_info=DestroyAESInfo(aes_info);
633  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
634  image->filename);
635  }
636  SetAESKey(aes_info,key);
637  key=DestroyStringInfo(key);
638  signature_info=AcquireSignatureInfo();
639  UpdateSignature(signature_info,nonce);
640  extent=(MagickSizeType) image->columns*image->rows;
641  SetStringInfoLength(nonce,sizeof(extent));
642  SetStringInfoDatum(nonce,(const unsigned char *) &extent);
643  UpdateSignature(signature_info,nonce);
644  nonce=DestroyStringInfo(nonce);
645  FinalizeSignature(signature_info);
646  (void) memset(input_block,0,sizeof(input_block));
647  digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
648  (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
649  GetSignatureDigestsize(signature_info))*sizeof(*input_block));
650  signature_info=DestroySignatureInfo(signature_info);
651  /*
652  Convert cipher pixels to plain pixels.
653  */
654  quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
655  if (quantum_info == (QuantumInfo *) NULL)
656  {
657  aes_info=DestroyAESInfo(aes_info);
658  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
659  image->filename);
660  }
661  quantum_type=GetQuantumType(image,exception);
662  pixels=GetQuantumPixels(quantum_info);
663  image_view=AcquireAuthenticCacheView(image,exception);
664  for (y=0; y < (ssize_t) image->rows; y++)
665  {
666  ssize_t
667  i,
668  x;
669 
671  *magick_restrict q;
672 
673  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
674  if (q == (PixelPacket *) NULL)
675  break;
676  length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
677  pixels,exception);
678  p=pixels;
679  for (x=0; x < (ssize_t) length; x+=AESBlocksize)
680  {
681  (void) memmove(output_block,input_block,AESBlocksize*
682  sizeof(*output_block));
683  IncrementCipherNonce(AESBlocksize,input_block);
684  EncipherAESBlock(aes_info,output_block,output_block);
685  for (i=0; i < AESBlocksize; i++)
686  p[i]^=output_block[i];
687  p+=AESBlocksize;
688  }
689  (void) memmove(output_block,input_block,AESBlocksize*sizeof(*output_block));
690  EncipherAESBlock(aes_info,output_block,output_block);
691  for (i=0; x < (ssize_t) length; x++)
692  {
693  p[i]^=output_block[i];
694  i++;
695  }
696  (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
697  pixels,exception);
698  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
699  break;
700  proceed=SetImageProgress(image,DecipherImageTag,(MagickOffsetType) y,
701  image->rows);
702  if (proceed == MagickFalse)
703  break;
704  }
705  image_view=DestroyCacheView(image_view);
706  (void) DeleteImageProperty(image,"cipher:type");
707  (void) DeleteImageProperty(image,"cipher:mode");
708  (void) DeleteImageProperty(image,"cipher:nonce");
709  image->taint=MagickFalse;
710  /*
711  Free resources.
712  */
713  quantum_info=DestroyQuantumInfo(quantum_info);
714  aes_info=DestroyAESInfo(aes_info);
715  (void) ResetMagickMemory(input_block,0,sizeof(input_block));
716  (void) ResetMagickMemory(output_block,0,sizeof(output_block));
717  return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
718 }
719 ␌
720 /*
721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
722 % %
723 % %
724 % %
725 % P a s s k e y E n c i p h e r I m a g e %
726 % %
727 % %
728 % %
729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
730 %
731 % PasskeyEncipherImage() converts pixels to cipher-pixels.
732 %
733 % The format of the PasskeyEncipherImage method is:
734 %
735 % MagickBooleanType PasskeyEncipherImage(Image *image,
736 % const StringInfo *passkey,ExceptionInfo *exception)
737 % MagickBooleanType EncipherImage(Image *image,const char *passphrase,
738 % ExceptionInfo *exception)
739 %
740 % A description of each parameter follows:
741 %
742 % o image: the image.
743 %
744 % o passphrase: encipher pixels with this passphrase.
745 %
746 % o passkey: decrypt cipher pixels with this passkey.
747 %
748 % o exception: return any errors or warnings in this structure.
749 %
750 */
751 
752 MagickExport MagickBooleanType EncipherImage(Image *image,
753  const char *passphrase,ExceptionInfo *exception)
754 {
755  MagickBooleanType
756  status;
757 
758  StringInfo
759  *passkey;
760 
761  if (passphrase == (const char *) NULL)
762  return(MagickTrue);
763  passkey=StringToStringInfo(passphrase);
764  if (passkey == (StringInfo *) NULL)
765  return(MagickFalse);
766  status=PasskeyEncipherImage(image,passkey,exception);
767  passkey=DestroyStringInfo(passkey);
768  return(status);
769 }
770 
771 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
772  const StringInfo *passkey,ExceptionInfo *exception)
773 {
774 #define EncipherImageTag "Encipher/Image "
775 
776  AESInfo
777  *aes_info;
778 
779  CacheView
780  *image_view;
781 
782  char
783  *signature;
784 
785  const unsigned char
786  *digest;
787 
788  MagickBooleanType
789  proceed;
790 
791  MagickSizeType
792  extent;
793 
795  *quantum_info;
796 
797  QuantumType
798  quantum_type;
799 
800  unsigned char
801  *p;
802 
804  *signature_info;
805 
806  size_t
807  length;
808 
809  ssize_t
810  y;
811 
812  StringInfo
813  *key,
814  *nonce;
815 
816  unsigned char
817  input_block[AESBlocksize],
818  output_block[AESBlocksize],
819  *pixels;
820 
821  /*
822  Generate encipher key and nonce.
823  */
824  assert(image != (Image *) NULL);
825  assert(image->signature == MagickCoreSignature);
826  assert(exception != (ExceptionInfo *) NULL);
827  assert(exception->signature == MagickCoreSignature);
828  if (IsEventLogging() != MagickFalse)
829  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
830  if (passkey == (const StringInfo *) NULL)
831  return(MagickTrue);
832  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
833  return(MagickFalse);
834  aes_info=AcquireAESInfo();
835  key=CloneStringInfo(passkey);
836  if (key == (StringInfo *) NULL)
837  {
838  aes_info=DestroyAESInfo(aes_info);
839  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
840  image->filename);
841  }
842  nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
843  if (nonce == (StringInfo *) NULL)
844  {
845  key=DestroyStringInfo(key);
846  aes_info=DestroyAESInfo(aes_info);
847  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
848  image->filename);
849  }
850  SetAESKey(aes_info,key);
851  key=DestroyStringInfo(key);
852  signature_info=AcquireSignatureInfo();
853  UpdateSignature(signature_info,nonce);
854  extent=(MagickSizeType) image->columns*image->rows;
855  SetStringInfoLength(nonce,sizeof(extent));
856  SetStringInfoDatum(nonce,(const unsigned char *) &extent);
857  UpdateSignature(signature_info,nonce);
858  nonce=DestroyStringInfo(nonce);
859  FinalizeSignature(signature_info);
860  (void) memset(input_block,0,sizeof(input_block));
861  digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
862  (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
863  GetSignatureDigestsize(signature_info))*sizeof(*input_block));
864  signature=StringInfoToHexString(GetSignatureDigest(signature_info));
865  (void) SetImageProperty(image,"cipher:type","AES");
866  (void) SetImageProperty(image,"cipher:mode","CTR");
867  (void) SetImageProperty(image,"cipher:nonce",signature);
868  signature=DestroyString(signature);
869  signature_info=DestroySignatureInfo(signature_info);
870  /*
871  Convert plain pixels to cipher pixels.
872  */
873  quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
874  if (quantum_info == (QuantumInfo *) NULL)
875  {
876  aes_info=DestroyAESInfo(aes_info);
877  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
878  image->filename);
879  }
880  quantum_type=GetQuantumType(image,exception);
881  pixels=GetQuantumPixels(quantum_info);
882  image_view=AcquireAuthenticCacheView(image,exception);
883  for (y=0; y < (ssize_t) image->rows; y++)
884  {
885  ssize_t
886  i,
887  x;
888 
890  *magick_restrict q;
891 
892  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
893  if (q == (PixelPacket *) NULL)
894  break;
895  length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
896  pixels,exception);
897  p=pixels;
898  for (x=0; x < (ssize_t) length; x+=AESBlocksize)
899  {
900  (void) memmove(output_block,input_block,AESBlocksize*
901  sizeof(*output_block));
902  IncrementCipherNonce(AESBlocksize,input_block);
903  EncipherAESBlock(aes_info,output_block,output_block);
904  for (i=0; i < AESBlocksize; i++)
905  p[i]^=output_block[i];
906  p+=AESBlocksize;
907  }
908  (void) memmove(output_block,input_block,AESBlocksize*
909  sizeof(*output_block));
910  EncipherAESBlock(aes_info,output_block,output_block);
911  for (i=0; x < (ssize_t) length; x++)
912  {
913  p[i]^=output_block[i];
914  i++;
915  }
916  (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
917  pixels,exception);
918  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
919  break;
920  proceed=SetImageProgress(image,EncipherImageTag,(MagickOffsetType) y,
921  image->rows);
922  if (proceed == MagickFalse)
923  break;
924  }
925  image_view=DestroyCacheView(image_view);
926  image->taint=MagickFalse;
927  /*
928  Free resources.
929  */
930  quantum_info=DestroyQuantumInfo(quantum_info);
931  aes_info=DestroyAESInfo(aes_info);
932  (void) ResetMagickMemory(input_block,0,sizeof(input_block));
933  (void) ResetMagickMemory(output_block,0,sizeof(output_block));
934  return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
935 }
936 ␌
937 /*
938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
939 % %
940 % %
941 % %
942 % S e t A E S K e y %
943 % %
944 % %
945 % %
946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
947 %
948 % SetAESKey() sets the key for the AES cipher. The key length is specified
949 % in bits. Valid values are 128, 192, or 256 requiring a key buffer length
950 % in bytes of 16, 24, and 32 respectively.
951 %
952 % The format of the SetAESKey method is:
953 %
954 % SetAESKey(AESInfo *aes_info,const StringInfo *key)
955 %
956 % A description of each parameter follows:
957 %
958 % o aes_info: the cipher context.
959 %
960 % o key: the key.
961 %
962 */
963 
964 static inline void InverseAddRoundKey(const unsigned int *alpha,
965  unsigned int *beta)
966 {
967  unsigned int
968  i,
969  j;
970 
971  for (i=0; i < 4; i++)
972  {
973  beta[i]=0;
974  for (j=0; j < 4; j++)
975  beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
976  ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
977  ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
978  ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
979  }
980 }
981 
982 static inline unsigned int XTime(unsigned char alpha)
983 {
984  unsigned char
985  beta;
986 
987  beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
988  alpha<<=1;
989  alpha^=beta;
990  return(alpha);
991 }
992 
993 static inline unsigned int RotateRight(const unsigned int x)
994 {
995  return((x >> 8) | ((x & 0xff) << 24));
996 }
997 
998 static void SetAESKey(AESInfo *aes_info,const StringInfo *key)
999 {
1000  ssize_t
1001  i;
1002 
1003  ssize_t
1004  bytes,
1005  n;
1006 
1007  unsigned char
1008  *datum;
1009 
1010  unsigned int
1011  alpha,
1012  beta;
1013 
1014  /*
1015  Determine the number of rounds based on the number of bits in key.
1016  */
1017  assert(aes_info != (AESInfo *) NULL);
1018  assert(aes_info->signature == MagickCoreSignature);
1019  assert(key != (StringInfo *) NULL);
1020  if (IsEventLogging() != MagickFalse)
1021  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1022  n=4;
1023  aes_info->rounds=10;
1024  if ((8*GetStringInfoLength(key)) >= 256)
1025  {
1026  n=8;
1027  aes_info->rounds=14;
1028  }
1029  else
1030  if ((8*GetStringInfoLength(key)) >= 192)
1031  {
1032  n=6;
1033  aes_info->rounds=12;
1034  }
1035  /*
1036  Generate crypt key.
1037  */
1038  datum=GetStringInfoDatum(aes_info->key);
1039  (void) memset(datum,0,GetStringInfoLength(aes_info->key));
1040  (void) memcpy(datum,GetStringInfoDatum(key),MagickMin(
1041  GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
1042  for (i=0; i < n; i++)
1043  aes_info->encipher_key[i]=(unsigned int) datum[4*i] |
1044  ((unsigned int) datum[4*i+1] << 8) |
1045  ((unsigned int) datum[4*i+2] << 16) |
1046  ((unsigned int) datum[4*i+3] << 24);
1047  beta=1;
1048  bytes=(AESBlocksize/4)*(aes_info->rounds+1);
1049  for (i=n; i < bytes; i++)
1050  {
1051  alpha=aes_info->encipher_key[i-1];
1052  if ((i % n) == 0)
1053  {
1054  alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
1055  beta=XTime((unsigned char) (beta & 0xff));
1056  }
1057  else
1058  if ((n > 6) && ((i % n) == 4))
1059  alpha=ByteSubTransform(alpha,SBox);
1060  aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
1061  }
1062  /*
1063  Generate decipher key (in reverse order).
1064  */
1065  for (i=0; i < 4; i++)
1066  {
1067  aes_info->decipher_key[i]=aes_info->encipher_key[i];
1068  aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
1069  }
1070  for (i=4; i < (bytes-4); i+=4)
1071  InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
1072  /*
1073  Reset registers.
1074  */
1075  datum=GetStringInfoDatum(aes_info->key);
1076  (void) memset(datum,0,GetStringInfoLength(aes_info->key));
1077  alpha=0;
1078  beta=0;
1079 }
1080 #else
1081 ␌
1082 /*
1083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1084 % %
1085 % %
1086 % %
1087 % P a s s k e y D e c i p h e r I m a g e %
1088 % %
1089 % %
1090 % %
1091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1092 %
1093 % PasskeyDecipherImage() converts cipher pixels to plain pixels.
1094 %
1095 % The format of the PasskeyDecipherImage method is:
1096 %
1097 % MagickBooleanType PasskeyDecipherImage(Image *image,
1098 % const StringInfo *passkey,ExceptionInfo *exception)
1099 % MagickBooleanType DecipherImage(Image *image,const char *passphrase,
1100 % ExceptionInfo *exception)
1101 %
1102 % A description of each parameter follows:
1103 %
1104 % o image: the image.
1105 %
1106 % o passphrase: decipher cipher pixels with this passphrase.
1107 %
1108 % o passkey: decrypt cipher pixels with this passkey.
1109 %
1110 % o exception: return any errors or warnings in this structure.
1111 %
1112 */
1113 
1114 MagickExport MagickBooleanType DecipherImage(Image *image,
1115  const char *passphrase,ExceptionInfo *exception)
1116 {
1117  assert(image != (Image *) NULL);
1118  assert(image->signature == MagickCoreSignature);
1119  assert(exception != (ExceptionInfo *) NULL);
1120  assert(exception->signature == MagickCoreSignature);
1121  if (IsEventLogging() != MagickFalse)
1122  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1123  (void) passphrase;
1124  ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1125 }
1126 
1127 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
1128  const StringInfo *passkey,ExceptionInfo *exception)
1129 {
1130  assert(image != (Image *) NULL);
1131  assert(image->signature == MagickCoreSignature);
1132  assert(exception != (ExceptionInfo *) NULL);
1133  assert(exception->signature == MagickCoreSignature);
1134  if (IsEventLogging() != MagickFalse)
1135  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1136  (void) passkey;
1137  ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1138 }
1139 ␌
1140 /*
1141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1142 % %
1143 % %
1144 % %
1145 % P a s s k e y E n c i p h e r I m a g e %
1146 % %
1147 % %
1148 % %
1149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1150 %
1151 % PasskeyEncipherImage() converts pixels to cipher-pixels.
1152 %
1153 % The format of the PasskeyEncipherImage method is:
1154 %
1155 % MagickBooleanType PasskeyEncipherImage(Image *image,
1156 % const StringInfo *passkey,ExceptionInfo *exception)
1157 % MagickBooleanType EncipherImage(Image *image,const char *passphrase,
1158 % ExceptionInfo *exception)
1159 %
1160 % A description of each parameter follows:
1161 %
1162 % o passphrase: decipher cipher pixels with this passphrase.
1163 %
1164 % o passkey: decrypt cipher pixels with this passkey.
1165 %
1166 % o exception: return any errors or warnings in this structure.
1167 %
1168 */
1169 
1170 MagickExport MagickBooleanType EncipherImage(Image *image,
1171  const char *passphrase,ExceptionInfo *exception)
1172 {
1173  assert(image != (Image *) NULL);
1174  assert(image->signature == MagickCoreSignature);
1175  assert(exception != (ExceptionInfo *) NULL);
1176  assert(exception->signature == MagickCoreSignature);
1177  if (IsEventLogging() != MagickFalse)
1178  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1179  (void) passphrase;
1180  ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1181 }
1182 
1183 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
1184  const StringInfo *passkey,ExceptionInfo *exception)
1185 {
1186  assert(image != (Image *) NULL);
1187  assert(image->signature == MagickCoreSignature);
1188  assert(exception != (ExceptionInfo *) NULL);
1189  assert(exception->signature == MagickCoreSignature);
1190  if (IsEventLogging() != MagickFalse)
1191  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1192  (void) passkey;
1193  ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1194 }
1195 #endif
Definition: image.h:134