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