MagickCore  7.1.0
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 @ 2003 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 ␌
63 #if defined(MAGICKCORE_CIPHER_SUPPORT)
64 /*
65  Define declarations.
66 */
67 #define AESBlocksize 16
68 ␌
69 /*
70  Typedef declarations.
71 */
72 typedef struct _AESInfo
73 {
75  *key;
76 
77  unsigned int
78  blocksize,
79  *encipher_key,
80  *decipher_key;
81 
82  ssize_t
83  rounds,
84  timestamp;
85 
86  size_t
87  signature;
88 } AESInfo;
89 ␌
90 /*
91  Global declarations.
92 */
93 static unsigned char
94  InverseLog[256] =
95  {
96  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248,
97  19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10,
98  30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190,
99  217, 112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204,
100  79, 209, 104, 184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59,
101  77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208,
102  107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196,
103  87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
104  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32,
105  96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86,
106  250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237,
107  44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126,
108  130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35,
109  101, 175, 234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99,
110  165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, 69, 207,
111  74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
112  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242,
113  13, 23, 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180,
114  199, 82, 246, 1
115  },
116  Log[256] =
117  {
118  0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238,
119  223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200,
120  248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228,
121  166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36,
122  18, 240, 130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208,
123  206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253, 48,
124  191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110,
125  72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
126  43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115,
127  167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213,
128  231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245, 89, 203,
129  95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236,
130  216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96,
131  177, 134, 59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144,
132  97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, 83, 57,
133  132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
134  68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153,
135  227, 165, 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128,
136  192, 247, 112, 7,
137  },
138  SBox[256] =
139  {
140  99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215,
141  171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175,
142  156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
143  229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154,
144  7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
145  90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237,
146  32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239,
147  170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
148  81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255,
149  243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
150  100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238,
151  184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92,
152  194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213,
153  78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46,
154  28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
155  181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
156  225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85,
157  40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15,
158  176, 84, 187, 22
159  };
160 ␌
161 /*
162  Forward declarations.
163 */
164 static AESInfo
165  *DestroyAESInfo(AESInfo *);
166 
167 static void
168  EncipherAESBlock(AESInfo *,const unsigned char *,unsigned char *),
169  SetAESKey(AESInfo *,const StringInfo *);
170 ␌
171 /*
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 % %
174 % %
175 % %
176 % A c q u i r e A E S I n f o %
177 % %
178 % %
179 % %
180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
181 %
182 % AcquireAESInfo() allocate the AESInfo structure.
183 %
184 % The format of the AcquireAESInfo method is:
185 %
186 % AESInfo *AcquireAESInfo(void)
187 %
188 */
189 static AESInfo *AcquireAESInfo(void)
190 {
191  AESInfo
192  *aes_info;
193 
194  aes_info=(AESInfo *) AcquireCriticalMemory(sizeof(*aes_info));
195  (void) memset(aes_info,0,sizeof(*aes_info));
196  aes_info->blocksize=AESBlocksize;
197  aes_info->key=AcquireStringInfo(32);
198  aes_info->encipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
199  *aes_info->encipher_key));
200  aes_info->decipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
201  *aes_info->decipher_key));
202  if ((aes_info->key == (StringInfo *) NULL) ||
203  (aes_info->encipher_key == (unsigned int *) NULL) ||
204  (aes_info->decipher_key == (unsigned int *) NULL))
205  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
206  aes_info->timestamp=(ssize_t) time(0);
207  aes_info->signature=MagickCoreSignature;
208  return(aes_info);
209 }
210 ␌
211 /*
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213 % %
214 % %
215 % %
216 % D e s t r o y A E S I n f o %
217 % %
218 % %
219 % %
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 %
222 % DestroyAESInfo() zeros memory associated with the AESInfo structure.
223 %
224 % The format of the DestroyAESInfo method is:
225 %
226 % AESInfo *DestroyAESInfo(AESInfo *aes_info)
227 %
228 % A description of each parameter follows:
229 %
230 % o aes_info: the cipher context.
231 %
232 */
233 static AESInfo *DestroyAESInfo(AESInfo *aes_info)
234 {
235  assert(aes_info != (AESInfo *) NULL);
236  assert(aes_info->signature == MagickCoreSignature);
237  if (IsEventLogging() != MagickFalse)
238  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
239  if (aes_info->decipher_key != (unsigned int *) NULL)
240  aes_info->decipher_key=(unsigned int *) RelinquishMagickMemory(
241  aes_info->decipher_key);
242  if (aes_info->encipher_key != (unsigned int *) NULL)
243  aes_info->encipher_key=(unsigned int *) RelinquishMagickMemory(
244  aes_info->encipher_key);
245  if (aes_info->key != (StringInfo *) NULL)
246  aes_info->key=DestroyStringInfo(aes_info->key);
247  aes_info->signature=(~MagickCoreSignature);
248  aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
249  return(aes_info);
250 }
251 ␌
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  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 int 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((unsigned int) 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=((unsigned int) s_box[x & 0xff]) |
315  ((unsigned int) s_box[(x >> 8) & 0xff] << 8) |
316  ((unsigned int) s_box[(x >> 16) & 0xff] << 16) |
317  ((unsigned int) s_box[(x >> 24) & 0xff] << 24);
318  return(key);
319 }
320 
321 static void FinalizeRoundKey(const unsigned int *ciphertext,
322  const unsigned int *key,unsigned char *plaintext)
323 {
324  unsigned char
325  *p;
326 
327  unsigned int
328  i,
329  j;
330 
331  unsigned int
332  value;
333 
334  /*
335  The round key is XORed with the result of the mix-column transformation.
336  */
337  p=plaintext;
338  for (i=0; i < 4; i++)
339  {
340  value=ciphertext[i] ^ key[i];
341  for (j=0; j < 4; j++)
342  *p++=(unsigned char) ((value >> (8*j)) & 0xff);
343  }
344  /*
345  Reset registers.
346  */
347  value=0;
348 }
349 
350 static void InitializeRoundKey(const unsigned char *ciphertext,
351  const unsigned int *key,unsigned int *plaintext)
352 {
353  const unsigned char
354  *p;
355 
356  unsigned int
357  i,
358  j;
359 
360  unsigned int
361  value;
362 
363  p=ciphertext;
364  for (i=0; i < 4; i++)
365  {
366  value=0;
367  for (j=0; j < 4; j++)
368  value|=((unsigned int) *p++ << (8*j));
369  plaintext[i]=key[i] ^ value;
370  }
371  /*
372  Reset registers.
373  */
374  value=0;
375 }
376 
377 static inline unsigned int RotateLeft(const unsigned int x)
378 {
379  return(((x << 8) | ((x >> 24) & 0xff)));
380 }
381 
382 static void EncipherAESBlock(AESInfo *aes_info,const unsigned char *plaintext,
383  unsigned char *ciphertext)
384 {
385  ssize_t
386  i,
387  j;
388 
389  static int
390  map[4][4] =
391  {
392  { 0, 1, 2, 3 },
393  { 1, 2, 3, 0 },
394  { 2, 3, 0, 1 },
395  { 3, 0, 1, 2 }
396  };
397 
398  static unsigned int
399  D[] =
400  {
401  0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
402  0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
403  0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
404  0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
405  0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
406  0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
407  0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
408  0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
409  0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
410  0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
411  0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
412  0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
413  0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
414  0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
415  0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
416  0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
417  0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
418  0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
419  0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
420  0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
421  0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
422  0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
423  0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
424  0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
425  0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
426  0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
427  0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
428  0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
429  0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
430  0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
431  0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
432  0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
433  0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
434  0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
435  0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
436  0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
437  0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
438  0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
439  0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
440  0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
441  0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
442  0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
443  0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
444  0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
445  0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
446  0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
447  0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
448  0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
449  0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
450  0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
451  0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
452  0x3a16162cU
453  };
454 
455  unsigned int
456  alpha,
457  key[4],
458  text[4];
459 
460  /*
461  Encipher one block.
462  */
463  (void) memset(text,0,sizeof(text));
464  InitializeRoundKey(plaintext,aes_info->encipher_key,text);
465  for (i=1; i < aes_info->rounds; i++)
466  {
467  /*
468  Linear mixing step: cause diffusion of the bits over multiple rounds.
469  */
470  for (j=0; j < 4; j++)
471  key[j]=D[text[j] & 0xff] ^
472  RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
473  RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
474  RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
475  AddRoundKey(key,aes_info->encipher_key+4*i,text);
476  }
477  for (i=0; i < 4; i++)
478  {
479  alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
480  ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
481  key[i]=ByteSubTransform(alpha,SBox);
482  }
483  FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
484  /*
485  Reset registers.
486  */
487  alpha=0;
488  (void) ResetMagickMemory(key,0,sizeof(key));
489  (void) ResetMagickMemory(text,0,sizeof(text));
490 }
491 ␌
492 /*
493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
494 % %
495 % %
496 % %
497 % P a s s k e y D e c i p h e r I m a g e %
498 % %
499 % %
500 % %
501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502 %
503 % PasskeyDecipherImage() converts cipher pixels to plain pixels.
504 %
505 % The format of the PasskeyDecipherImage method is:
506 %
507 % MagickBooleanType PasskeyDecipherImage(Image *image,
508 % const StringInfo *passkey,ExceptionInfo *exception)
509 % MagickBooleanType DecipherImage(Image *image,const char *passphrase,
510 % ExceptionInfo *exception)
511 %
512 % A description of each parameter follows:
513 %
514 % o image: the image.
515 %
516 % o passphrase: decipher cipher pixels with this passphrase.
517 %
518 % o passkey: decrypt cipher pixels with this passkey.
519 %
520 % o exception: return any errors or warnings in this structure.
521 %
522 */
523 
524 static inline void IncrementCipherNonce(const size_t length,
525  unsigned char *nonce)
526 {
527  ssize_t
528  i;
529 
530  for (i=(ssize_t) (length-1); i >= 0; i--)
531  {
532  nonce[i]++;
533  if (nonce[i] != 0)
534  return;
535  }
536  ThrowFatalException(ResourceLimitFatalError,"Sequence wrap error `%s'");
537 }
538 
539 MagickExport MagickBooleanType DecipherImage(Image *image,
540  const char *passphrase,ExceptionInfo *exception)
541 {
542  MagickBooleanType
543  status;
544 
545  StringInfo
546  *passkey;
547 
548  if (passphrase == (const char *) NULL)
549  return(MagickTrue);
550  passkey=StringToStringInfo(passphrase);
551  if (passkey == (StringInfo *) NULL)
552  return(MagickFalse);
553  status=PasskeyDecipherImage(image,passkey,exception);
554  passkey=DestroyStringInfo(passkey);
555  return(status);
556 }
557 
558 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
559  const StringInfo *passkey,ExceptionInfo *exception)
560 {
561 #define DecipherImageTag "Decipher/Image "
562 
563  AESInfo
564  *aes_info;
565 
566  CacheView
567  *image_view;
568 
569  const unsigned char
570  *digest;
571 
572  MagickBooleanType
573  proceed;
574 
575  MagickSizeType
576  extent;
577 
579  *quantum_info;
580 
581  QuantumType
582  quantum_type;
583 
585  *signature_info;
586 
587  unsigned char
588  *p;
589 
590  size_t
591  length;
592 
593  ssize_t
594  y;
595 
596  StringInfo
597  *key,
598  *nonce;
599 
600  unsigned char
601  input_block[AESBlocksize],
602  output_block[AESBlocksize],
603  *pixels;
604 
605  /*
606  Generate decipher key and nonce.
607  */
608  assert(image != (Image *) NULL);
609  assert(image->signature == MagickCoreSignature);
610  assert(exception != (ExceptionInfo *) NULL);
611  assert(exception->signature == MagickCoreSignature);
612  if (IsEventLogging() != MagickFalse)
613  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
614  if (passkey == (const StringInfo *) NULL)
615  return(MagickTrue);
616  aes_info=AcquireAESInfo();
617  key=CloneStringInfo(passkey);
618  if (key == (StringInfo *) NULL)
619  {
620  aes_info=DestroyAESInfo(aes_info);
621  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
622  image->filename);
623  }
624  nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
625  if (nonce == (StringInfo *) NULL)
626  {
627  key=DestroyStringInfo(key);
628  aes_info=DestroyAESInfo(aes_info);
629  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
630  image->filename);
631  }
632  SetAESKey(aes_info,key);
633  key=DestroyStringInfo(key);
634  signature_info=AcquireSignatureInfo();
635  UpdateSignature(signature_info,nonce);
636  extent=(MagickSizeType) image->columns*image->rows;
637  SetStringInfoLength(nonce,sizeof(extent));
638  SetStringInfoDatum(nonce,(const unsigned char *) &extent);
639  UpdateSignature(signature_info,nonce);
640  nonce=DestroyStringInfo(nonce);
641  FinalizeSignature(signature_info);
642  (void) memset(input_block,0,sizeof(input_block));
643  digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
644  (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
645  GetSignatureDigestsize(signature_info))*sizeof(*input_block));
646  signature_info=DestroySignatureInfo(signature_info);
647  /*
648  Convert cipher pixels to plain pixels.
649  */
650  quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
651  if (quantum_info == (QuantumInfo *) NULL)
652  {
653  aes_info=DestroyAESInfo(aes_info);
654  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
655  image->filename);
656  }
657  quantum_type=GetQuantumType(image,exception);
658  pixels=(unsigned char *) GetQuantumPixels(quantum_info);
659  image_view=AcquireAuthenticCacheView(image,exception);
660  for (y=0; y < (ssize_t) image->rows; y++)
661  {
662  ssize_t
663  i,
664  x;
665 
666  Quantum
667  *magick_restrict q;
668 
669  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
670  if (q == (Quantum *) NULL)
671  break;
672  length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
673  pixels,exception);
674  p=pixels;
675  for (x=0; x < (ssize_t) length; x+=AESBlocksize)
676  {
677  (void) memcpy(output_block,input_block,AESBlocksize*
678  sizeof(*output_block));
679  IncrementCipherNonce(AESBlocksize,input_block);
680  EncipherAESBlock(aes_info,output_block,output_block);
681  for (i=0; i < AESBlocksize; i++)
682  p[i]^=output_block[i];
683  p+=AESBlocksize;
684  }
685  (void) memcpy(output_block,input_block,AESBlocksize*
686  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,exception) == 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  signature=StringInfoToHexString(GetSignatureDigest(signature_info));
858  (void) SetImageProperty(image,"cipher:type","AES",exception);
859  (void) SetImageProperty(image,"cipher:mode","CTR",exception);
860  (void) SetImageProperty(image,"cipher:nonce",signature,exception);
861  signature=DestroyString(signature);
862  (void) memset(input_block,0,sizeof(input_block));
863  digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
864  (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
865  GetSignatureDigestsize(signature_info))*sizeof(*input_block));
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=(unsigned char *) 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 
886  Quantum
887  *magick_restrict q;
888 
889  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
890  if (q == (Quantum *) 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) memcpy(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) memcpy(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