source: ImageMagick/trunk/MagickCore/cipher.c @ 8316

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