]> granicus.if.org Git - imagemagick/blob - MagickCore/cipher.c
(no commit message)
[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 %                               John Cristy                                   %
16 %                               March  2003                                   %
17 %                                                                             %
18 %                                                                             %
19 %  Copyright 1999-2013 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 %    http://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/hashmap.h"
47 #include "MagickCore/image.h"
48 #include "MagickCore/image-private.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=MagickSignature;
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 == MagickSignature);
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=(~MagickSignature);
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 static inline size_t MagickMin(const size_t x,const size_t y)
538 {
539   if (x < y)
540     return(x);
541   return(y);
542 }
543
544 MagickExport MagickBooleanType DecipherImage(Image *image,
545   const char *passphrase,ExceptionInfo *exception)
546 {
547   MagickBooleanType
548     status;
549
550   StringInfo
551     *passkey;
552
553   if (passphrase == (const char *) NULL)
554     return(MagickTrue);
555   passkey=StringToStringInfo(passphrase);
556   if (passkey == (StringInfo *) NULL)
557     return(MagickFalse);
558   status=PasskeyDecipherImage(image,passkey,exception);
559   passkey=DestroyStringInfo(passkey);
560   return(status);
561 }
562
563 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
564   const StringInfo *passkey,ExceptionInfo *exception)
565 {
566 #define DecipherImageTag  "Decipher/Image "
567
568   AESInfo
569     *aes_info;
570
571   CacheView
572     *image_view;
573
574   const unsigned char
575     *digest;
576
577   MagickBooleanType
578     proceed;
579
580   MagickSizeType
581     extent;
582
583   QuantumInfo
584     *quantum_info;
585
586   QuantumType
587     quantum_type;
588
589   SignatureInfo
590     *signature_info;
591
592   register unsigned char
593     *p;
594
595   size_t
596     length;
597
598   ssize_t
599     y;
600
601   StringInfo
602     *key,
603     *nonce;
604
605   unsigned char
606     input_block[AESBlocksize],
607     output_block[AESBlocksize],
608     *pixels;
609
610   /*
611     Generate decipher key and nonce.
612   */
613   assert(image != (Image *) NULL);
614   assert(image->signature == MagickSignature);
615   if (image->debug != MagickFalse)
616     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
617   assert(exception != (ExceptionInfo *) NULL);
618   assert(exception->signature == MagickSignature);
619   if (passkey == (const StringInfo *) NULL)
620     return(MagickTrue);
621   aes_info=AcquireAESInfo();
622   key=CloneStringInfo(passkey);
623   if (key == (StringInfo *) NULL)
624     {
625       aes_info=DestroyAESInfo(aes_info);
626       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
627         image->filename);
628     }
629   nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
630   if (nonce == (StringInfo *) NULL)
631     {
632       key=DestroyStringInfo(key);
633       aes_info=DestroyAESInfo(aes_info);
634       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
635         image->filename);
636     }
637   SetAESKey(aes_info,key);
638   key=DestroyStringInfo(key);
639   signature_info=AcquireSignatureInfo();
640   UpdateSignature(signature_info,nonce);
641   extent=(MagickSizeType) image->columns*image->rows;
642   SetStringInfoLength(nonce,sizeof(extent));
643   SetStringInfoDatum(nonce,(const unsigned char *) &extent);
644   UpdateSignature(signature_info,nonce);
645   nonce=DestroyStringInfo(nonce);
646   FinalizeSignature(signature_info);
647   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
648   digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
649   (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
650     GetSignatureDigestsize(signature_info))*sizeof(*input_block));
651   signature_info=DestroySignatureInfo(signature_info);
652   /*
653     Convert cipher pixels to plain pixels.
654   */
655   quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
656   if (quantum_info == (QuantumInfo *) NULL)
657     {
658       aes_info=DestroyAESInfo(aes_info);
659       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
660         image->filename);
661     }
662   quantum_type=GetQuantumType(image,exception);
663   pixels=GetQuantumPixels(quantum_info);
664   image_view=AcquireAuthenticCacheView(image,exception);
665   for (y=0; y < (ssize_t) image->rows; y++)
666   {
667     register ssize_t
668       i,
669       x;
670
671     register Quantum
672       *restrict q;
673
674     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
675     if (q == (Quantum *) NULL)
676       break;
677     length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
678       pixels,exception);
679     p=pixels;
680     for (x=0; x < (ssize_t) length; x+=AESBlocksize)
681     {
682       (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
683         sizeof(*output_block));
684       IncrementCipherNonce(AESBlocksize,input_block);
685       EncipherAESBlock(aes_info,output_block,output_block);
686       for (i=0; i < AESBlocksize; i++)
687         p[i]^=output_block[i];
688       p+=AESBlocksize;
689     }
690     (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
691       sizeof(*output_block));
692     EncipherAESBlock(aes_info,output_block,output_block);
693     for (i=0; x < (ssize_t) length; x++)
694     {
695       p[i]^=output_block[i];
696       i++;
697     }
698     (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
699       pixels,exception);
700     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
701       break;
702     proceed=SetImageProgress(image,DecipherImageTag,(MagickOffsetType) y,
703       image->rows);
704     if (proceed == MagickFalse)
705       break;
706   }
707   image_view=DestroyCacheView(image_view);
708   (void) DeleteImageProperty(image,"cipher:type");
709   (void) DeleteImageProperty(image,"cipher:mode");
710   (void) DeleteImageProperty(image,"cipher:nonce");
711   image->taint=MagickFalse;
712   /*
713     Free resources.
714   */
715   quantum_info=DestroyQuantumInfo(quantum_info);
716   aes_info=DestroyAESInfo(aes_info);
717   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
718   (void) ResetMagickMemory(output_block,0,sizeof(output_block));
719   return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
720 }
721 \f
722 /*
723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
724 %                                                                             %
725 %                                                                             %
726 %                                                                             %
727 %     P a s s k e y E n c i p h e r I m a g e                                 %
728 %                                                                             %
729 %                                                                             %
730 %                                                                             %
731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
732 %
733 %  PasskeyEncipherImage() converts pixels to cipher-pixels.
734 %
735 %  The format of the PasskeyEncipherImage method is:
736 %
737 %      MagickBooleanType PasskeyEncipherImage(Image *image,
738 %        const StringInfo *passkey,ExceptionInfo *exception)
739 %      MagickBooleanType EncipherImage(Image *image,const char *passphrase,
740 %        ExceptionInfo *exception)
741 %
742 %  A description of each parameter follows:
743 %
744 %    o image: the image.
745 %
746 %    o passphrase: encipher pixels with this passphrase.
747 %
748 %    o passkey: decrypt cipher pixels with this passkey.
749 %
750 %    o exception: return any errors or warnings in this structure.
751 %
752 */
753
754 MagickExport MagickBooleanType EncipherImage(Image *image,
755   const char *passphrase,ExceptionInfo *exception)
756 {
757   MagickBooleanType
758     status;
759
760   StringInfo
761     *passkey;
762
763   if (passphrase == (const char *) NULL)
764     return(MagickTrue);
765   passkey=StringToStringInfo(passphrase);
766   if (passkey == (StringInfo *) NULL)
767     return(MagickFalse);
768   status=PasskeyEncipherImage(image,passkey,exception);
769   passkey=DestroyStringInfo(passkey);
770   return(status);
771 }
772
773 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
774   const StringInfo *passkey,ExceptionInfo *exception)
775 {
776 #define EncipherImageTag  "Encipher/Image "
777
778   AESInfo
779     *aes_info;
780
781   CacheView
782     *image_view;
783
784   char
785     *signature;
786
787   const unsigned char
788     *digest;
789
790   MagickBooleanType
791     proceed;
792
793   MagickSizeType
794     extent;
795
796   QuantumInfo
797     *quantum_info;
798
799   QuantumType
800     quantum_type;
801
802   register unsigned char
803     *p;
804
805   SignatureInfo
806     *signature_info;
807
808   size_t
809     length;
810
811   ssize_t
812     y;
813
814   StringInfo
815     *key,
816     *nonce;
817
818   unsigned char
819     input_block[AESBlocksize],
820     output_block[AESBlocksize],
821     *pixels;
822
823   /*
824     Generate encipher key and nonce.
825   */
826   assert(image != (Image *) NULL);
827   assert(image->signature == MagickSignature);
828   if (image->debug != MagickFalse)
829     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
830   assert(exception != (ExceptionInfo *) NULL);
831   assert(exception->signature == MagickSignature);
832   if (passkey == (const StringInfo *) NULL)
833     return(MagickTrue);
834   if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
835     return(MagickFalse);
836   aes_info=AcquireAESInfo();
837   key=CloneStringInfo(passkey);
838   if (key == (StringInfo *) NULL)
839     {
840       aes_info=DestroyAESInfo(aes_info);
841       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
842         image->filename);
843     }
844   nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
845   if (nonce == (StringInfo *) NULL)
846     {
847       key=DestroyStringInfo(key);
848       aes_info=DestroyAESInfo(aes_info);
849       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
850         image->filename);
851     }
852   SetAESKey(aes_info,key);
853   key=DestroyStringInfo(key);
854   signature_info=AcquireSignatureInfo();
855   UpdateSignature(signature_info,nonce);
856   extent=(MagickSizeType) image->columns*image->rows;
857   SetStringInfoLength(nonce,sizeof(extent));
858   SetStringInfoDatum(nonce,(const unsigned char *) &extent);
859   UpdateSignature(signature_info,nonce);
860   nonce=DestroyStringInfo(nonce);
861   FinalizeSignature(signature_info);
862   signature=StringInfoToHexString(GetSignatureDigest(signature_info));
863   (void) SetImageProperty(image,"cipher:type","AES",exception);
864   (void) SetImageProperty(image,"cipher:mode","CTR",exception);
865   (void) SetImageProperty(image,"cipher:nonce",signature,exception);
866   signature=DestroyString(signature);
867   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
868   digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
869   (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
870     GetSignatureDigestsize(signature_info))*sizeof(*input_block));
871   signature_info=DestroySignatureInfo(signature_info);
872   /*
873     Convert plain pixels to cipher pixels.
874   */
875   quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
876   if (quantum_info == (QuantumInfo *) NULL)
877     {
878       aes_info=DestroyAESInfo(aes_info);
879       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
880         image->filename);
881     }
882   quantum_type=GetQuantumType(image,exception);
883   pixels=GetQuantumPixels(quantum_info);
884   image_view=AcquireAuthenticCacheView(image,exception);
885   for (y=0; y < (ssize_t) image->rows; y++)
886   {
887     register ssize_t
888       i,
889       x;
890
891     register Quantum
892       *restrict q;
893
894     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
895     if (q == (Quantum *) NULL)
896       break;
897     length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
898       pixels,exception);
899     p=pixels;
900     for (x=0; x < (ssize_t) length; x+=AESBlocksize)
901     {
902       (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
903         sizeof(*output_block));
904       IncrementCipherNonce(AESBlocksize,input_block);
905       EncipherAESBlock(aes_info,output_block,output_block);
906       for (i=0; i < AESBlocksize; i++)
907         p[i]^=output_block[i];
908       p+=AESBlocksize;
909     }
910     (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
911       sizeof(*output_block));
912     EncipherAESBlock(aes_info,output_block,output_block);
913     for (i=0; x < (ssize_t) length; x++)
914     {
915       p[i]^=output_block[i];
916       i++;
917     }
918     (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
919       pixels,exception);
920     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
921       break;
922     proceed=SetImageProgress(image,EncipherImageTag,(MagickOffsetType) y,
923       image->rows);
924     if (proceed == MagickFalse)
925       break;
926   }
927   image_view=DestroyCacheView(image_view);
928   image->taint=MagickFalse;
929   /*
930     Free resources.
931   */
932   quantum_info=DestroyQuantumInfo(quantum_info);
933   aes_info=DestroyAESInfo(aes_info);
934   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
935   (void) ResetMagickMemory(output_block,0,sizeof(output_block));
936   return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
937 }
938 \f
939 /*
940 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941 %                                                                             %
942 %                                                                             %
943 %                                                                             %
944 %   S e t A E S K e y                                                         %
945 %                                                                             %
946 %                                                                             %
947 %                                                                             %
948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949 %
950 %  SetAESKey() sets the key for the AES cipher.  The key length is specified
951 %  in bits.  Valid values are 128, 192, or 256 requiring a key buffer length
952 %  in bytes of 16, 24, and 32 respectively.
953 %
954 %  The format of the SetAESKey method is:
955 %
956 %      SetAESKey(AESInfo *aes_info,const StringInfo *key)
957 %
958 %  A description of each parameter follows:
959 %
960 %    o aes_info: the cipher context.
961 %
962 %    o key: the key.
963 %
964 */
965
966 static inline void InverseAddRoundKey(const unsigned int *alpha,
967   unsigned int *beta)
968 {
969   register unsigned int
970     i,
971     j;
972
973   for (i=0; i < 4; i++)
974   {
975     beta[i]=0;
976     for (j=0; j < 4; j++)
977       beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
978         ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
979         ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
980         ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
981   }
982 }
983
984 static inline unsigned int XTime(unsigned char alpha)
985 {
986   unsigned char
987     beta;
988
989   beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
990   alpha<<=1;
991   alpha^=beta;
992   return(alpha);
993 }
994
995 static inline unsigned int RotateRight(const unsigned int x)
996 {
997   return((x >> 8) | ((x & 0xff) << 24));
998 }
999
1000 static void SetAESKey(AESInfo *aes_info,const StringInfo *key)
1001 {
1002   register ssize_t
1003     i;
1004
1005   ssize_t
1006     bytes,
1007     n;
1008
1009   unsigned char
1010     *datum;
1011
1012   unsigned int
1013     alpha,
1014     beta;
1015
1016   /*
1017     Determine the number of rounds based on the number of bits in key.
1018   */
1019   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1020   assert(aes_info != (AESInfo *) NULL);
1021   assert(aes_info->signature == MagickSignature);
1022   assert(key != (StringInfo *) NULL);
1023   n=4;
1024   aes_info->rounds=10;
1025   if ((8*GetStringInfoLength(key)) >= 256)
1026     {
1027       n=8;
1028       aes_info->rounds=14;
1029     }
1030   else
1031     if ((8*GetStringInfoLength(key)) >= 192)
1032       {
1033         n=6;
1034         aes_info->rounds=12;
1035       }
1036   /*
1037     Generate crypt key.
1038   */
1039   datum=GetStringInfoDatum(aes_info->key);
1040   (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
1041   (void) CopyMagickMemory(datum,GetStringInfoDatum(key),MagickMin(
1042     GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
1043   for (i=0; i < n; i++)
1044     aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) |
1045       (datum[4*i+2] << 16) | (datum[4*i+3] << 24);
1046   beta=1;
1047   bytes=(AESBlocksize/4)*(aes_info->rounds+1);
1048   for (i=n; i < bytes; i++)
1049   {
1050     alpha=aes_info->encipher_key[i-1];
1051     if ((i % n) == 0)
1052       {
1053         alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
1054         beta=XTime((unsigned char) (beta & 0xff));
1055       }
1056     else
1057       if ((n > 6) && ((i % n) == 4))
1058         alpha=ByteSubTransform(alpha,SBox);
1059     aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
1060   }
1061   /*
1062     Generate deciper key (in reverse order).
1063   */
1064   for (i=0; i < 4; i++)
1065   {
1066     aes_info->decipher_key[i]=aes_info->encipher_key[i];
1067     aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
1068   }
1069   for (i=4; i < (bytes-4); i+=4)
1070     InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
1071   /*
1072     Reset registers.
1073   */
1074   datum=GetStringInfoDatum(aes_info->key);
1075   (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
1076   alpha=0;
1077   beta=0;
1078 }
1079 #else
1080 \f
1081 /*
1082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1083 %                                                                             %
1084 %                                                                             %
1085 %                                                                             %
1086 %     P a s s k e y D e c i p h e r I m a g e                                 %
1087 %                                                                             %
1088 %                                                                             %
1089 %                                                                             %
1090 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1091 %
1092 %  PasskeyDecipherImage() converts cipher pixels to plain pixels.
1093 %
1094 %  The format of the PasskeyDecipherImage method is:
1095 %
1096 %      MagickBooleanType PasskeyDecipherImage(Image *image,
1097 %        const StringInfo *passkey,ExceptionInfo *exception)
1098 %      MagickBooleanType DecipherImage(Image *image,const char *passphrase,
1099 %        ExceptionInfo *exception)
1100 %
1101 %  A description of each parameter follows:
1102 %
1103 %    o image: the image.
1104 %
1105 %    o passphrase: decipher cipher pixels with this passphrase.
1106 %
1107 %    o passkey: decrypt cipher pixels with this passkey.
1108 %
1109 %    o exception: return any errors or warnings in this structure.
1110 %
1111 */
1112
1113 MagickExport MagickBooleanType DecipherImage(Image *image,
1114   const char *passphrase,ExceptionInfo *exception)
1115 {
1116   assert(image != (Image *) NULL);
1117   assert(image->signature == MagickSignature);
1118   if (image->debug != MagickFalse)
1119     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1120   assert(exception != (ExceptionInfo *) NULL);
1121   assert(exception->signature == MagickSignature);
1122   (void) passphrase;
1123   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1124 }
1125
1126 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
1127   const StringInfo *passkey,ExceptionInfo *exception)
1128 {
1129   assert(image != (Image *) NULL);
1130   assert(image->signature == MagickSignature);
1131   if (image->debug != MagickFalse)
1132     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1133   assert(exception != (ExceptionInfo *) NULL);
1134   assert(exception->signature == MagickSignature);
1135   (void) passkey;
1136   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1137 }
1138 \f
1139 /*
1140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1141 %                                                                             %
1142 %                                                                             %
1143 %                                                                             %
1144 %     P a s s k e y E n c i p h e r I m a g e                                 %
1145 %                                                                             %
1146 %                                                                             %
1147 %                                                                             %
1148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1149 %
1150 %  PasskeyEncipherImage() converts pixels to cipher-pixels.
1151 %
1152 %  The format of the PasskeyEncipherImage method is:
1153 %
1154 %      MagickBooleanType PasskeyEncipherImage(Image *image,
1155 %        const StringInfo *passkey,ExceptionInfo *exception)
1156 %      MagickBooleanType EncipherImage(Image *image,const char *passphrase,
1157 %        ExceptionInfo *exception)
1158 %
1159 %  A description of each parameter follows:
1160 %
1161 %    o passphrase: decipher cipher pixels with this passphrase.
1162 %
1163 %    o passkey: decrypt cipher pixels with this passkey.
1164 %
1165 %    o exception: return any errors or warnings in this structure.
1166 %
1167 */
1168
1169 MagickExport MagickBooleanType EncipherImage(Image *image,
1170   const char *passphrase,ExceptionInfo *exception)
1171 {
1172   assert(image != (Image *) NULL);
1173   assert(image->signature == MagickSignature);
1174   if (image->debug != MagickFalse)
1175     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1176   assert(exception != (ExceptionInfo *) NULL);
1177   assert(exception->signature == MagickSignature);
1178   (void) passphrase;
1179   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1180 }
1181
1182 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
1183   const StringInfo *passkey,ExceptionInfo *exception)
1184 {
1185   assert(image != (Image *) NULL);
1186   assert(image->signature == MagickSignature);
1187   if (image->debug != MagickFalse)
1188     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1189   assert(exception != (ExceptionInfo *) NULL);
1190   assert(exception->signature == MagickSignature);
1191   (void) passkey;
1192   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1193 }
1194 #endif