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