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