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