MagickCore  6.7.5
cipher.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                   CCCC  IIIII  PPPP   H   H  EEEEE  RRRR                    %
00006 %                  C        I    P   P  H   H  E      R   R                   %
00007 %                  C        I    PPPP   HHHHH  EEE    RRRR                    %
00008 %                  C        I    P      H   H  E      R R                     %
00009 %                   CCCC  IIIII  P      H   H  EEEEE  R  R                    %
00010 %                                                                             %
00011 %                                                                             %
00012 %                          MagickCore Cipher Methods                          %
00013 %                                                                             %
00014 %                             Software Design                                 %
00015 %                               John Cristy                                   %
00016 %                               March  2003                                   %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.imagemagick.org/script/license.php                            %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 %
00036 */
00037 
00038 /*
00039   Include declarations.
00040 */
00041 #include "MagickCore/studio.h"
00042 #include "MagickCore/cache.h"
00043 #include "MagickCore/cipher.h"
00044 #include "MagickCore/exception.h"
00045 #include "MagickCore/exception-private.h"
00046 #include "MagickCore/hashmap.h"
00047 #include "MagickCore/image.h"
00048 #include "MagickCore/image-private.h"
00049 #include "MagickCore/list.h"
00050 #include "MagickCore/memory_.h"
00051 #include "MagickCore/monitor.h"
00052 #include "MagickCore/monitor-private.h"
00053 #include "MagickCore/property.h"
00054 #include "MagickCore/quantum-private.h"
00055 #include "MagickCore/registry.h"
00056 #include "MagickCore/semaphore.h"
00057 #include "MagickCore/signature-private.h"
00058 #include "MagickCore/splay-tree.h"
00059 #include "MagickCore/statistic.h"
00060 #include "MagickCore/string_.h"
00061 
00062 #if defined(MAGICKCORE_CIPHER_SUPPORT)
00063 /*
00064   Define declarations.
00065 */
00066 #define AESBlocksize 16
00067 
00068 /*
00069   Typedef declarations.
00070 */
00071 typedef struct _AESInfo
00072 {
00073   StringInfo
00074     *key;
00075 
00076   unsigned int
00077     blocksize,
00078     *encipher_key,
00079     *decipher_key;
00080 
00081   ssize_t
00082     rounds,
00083     timestamp;
00084 
00085   size_t
00086     signature;
00087 } AESInfo;
00088 
00089 /*
00090   Global declarations.
00091 */
00092 static unsigned char
00093   InverseLog[256] =
00094   {
00095       1,   3,   5,  15,  17,  51,  85, 255,  26,  46, 114, 150, 161, 248,
00096      19,  53,  95, 225,  56,  72, 216, 115, 149, 164, 247,   2,   6,  10,
00097      30,  34, 102, 170, 229,  52,  92, 228,  55,  89, 235,  38, 106, 190,
00098     217, 112, 144, 171, 230,  49,  83, 245,   4,  12,  20,  60,  68, 204,
00099      79, 209, 104, 184, 211, 110, 178, 205,  76, 212, 103, 169, 224,  59,
00100      77, 215,  98, 166, 241,   8,  24,  40, 120, 136, 131, 158, 185, 208,
00101     107, 189, 220, 127, 129, 152, 179, 206,  73, 219, 118, 154, 181, 196,
00102      87, 249,  16,  48,  80, 240,  11,  29,  39, 105, 187, 214,  97, 163,
00103     254,  25,  43, 125, 135, 146, 173, 236,  47, 113, 147, 174, 233,  32,
00104      96, 160, 251,  22,  58,  78, 210, 109, 183, 194,  93, 231,  50,  86,
00105     250,  21,  63,  65, 195,  94, 226,  61,  71, 201,  64, 192,  91, 237,
00106      44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239,  42, 126,
00107     130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193,  88, 232,  35,
00108     101, 175, 234,  37, 111, 177, 200,  67, 197,  84, 252,  31,  33,  99,
00109     165, 244,   7,   9,  27,  45, 119, 153, 176, 203,  70, 202,  69, 207,
00110      74, 222, 121, 139, 134, 145, 168, 227,  62,  66, 198,  81, 243,  14,
00111      18,  54,  90, 238,  41, 123, 141, 140, 143, 138, 133, 148, 167, 242,
00112      13,  23,  57,  75, 221, 124, 132, 151, 162, 253,  28,  36, 108, 180,
00113     199,  82, 246,   1
00114   },
00115   Log[256] =
00116   {
00117       0,   0,  25,   1,  50,   2,  26, 198,  75, 199,  27, 104,  51, 238,
00118     223,   3, 100,   4, 224,  14,  52, 141, 129, 239,  76, 113,   8, 200,
00119     248, 105,  28, 193, 125, 194,  29, 181, 249, 185,  39, 106,  77, 228,
00120     166, 114, 154, 201,   9, 120, 101,  47, 138,   5,  33,  15, 225,  36,
00121      18, 240, 130,  69,  53, 147, 218, 142, 150, 143, 219, 189,  54, 208,
00122     206, 148,  19,  92, 210, 241,  64,  70, 131,  56, 102, 221, 253,  48,
00123     191,   6, 139,  98, 179,  37, 226, 152,  34, 136, 145,  16, 126, 110,
00124      72, 195, 163, 182,  30,  66,  58, 107,  40,  84, 250, 133,  61, 186,
00125      43, 121,  10,  21, 155, 159,  94, 202,  78, 212, 172, 229, 243, 115,
00126     167,  87, 175,  88, 168,  80, 244, 234, 214, 116,  79, 174, 233, 213,
00127     231, 230, 173, 232,  44, 215, 117, 122, 235,  22,  11, 245,  89, 203,
00128      95, 176, 156, 169,  81, 160, 127,  12, 246, 111,  23, 196,  73, 236,
00129     216,  67,  31,  45, 164, 118, 123, 183, 204, 187,  62,  90, 251,  96,
00130     177, 134,  59,  82, 161, 108, 170,  85,  41, 157, 151, 178, 135, 144,
00131      97, 190, 220, 252, 188, 149, 207, 205,  55,  63,  91, 209,  83,  57,
00132     132, 60,   65, 162, 109,  71,  20,  42, 158,  93,  86, 242, 211, 171,
00133      68,  17, 146, 217,  35,  32,  46, 137, 180, 124, 184,  38, 119, 153,
00134     227, 165, 103,  74, 237, 222, 197,  49, 254,  24,  13,  99, 140, 128,
00135     192, 247, 112,   7,
00136   },
00137   SBox[256] =
00138   {
00139      99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215,
00140     171, 118, 202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175,
00141     156, 164, 114, 192, 183, 253, 147,  38,  54,  63, 247, 204,  52, 165,
00142     229, 241, 113, 216,  49,  21,   4, 199,  35, 195,  24, 150,   5, 154,
00143       7,  18, 128, 226, 235,  39, 178, 117,   9, 131,  44,  26,  27, 110,
00144      90, 160,  82,  59, 214, 179,  41, 227,  47, 132,  83, 209,   0, 237,
00145      32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 208, 239,
00146     170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168,
00147      81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255,
00148     243, 210, 205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61,
00149     100,  93,  25, 115,  96, 129,  79, 220,  34,  42, 144, 136,  70, 238,
00150     184,  20, 222,  94,  11, 219, 224,  50,  58,  10,  73,   6,  36,  92,
00151     194, 211, 172,  98, 145, 149, 228, 121, 231, 200,  55, 109, 141, 213,
00152      78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 186, 120,  37,  46,
00153      28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 112,  62,
00154     181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158,
00155     225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,
00156      40, 223, 140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15,
00157     176,  84, 187, 22
00158   };
00159 
00160 /*
00161   Forward declarations.
00162 */
00163 static AESInfo
00164   *DestroyAESInfo(AESInfo *);
00165 
00166 static void
00167   EncipherAESBlock(AESInfo *,const unsigned char *,unsigned char *),
00168   SetAESKey(AESInfo *,const StringInfo *);
00169 
00170 /*
00171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00172 %                                                                             %
00173 %                                                                             %
00174 %                                                                             %
00175 %   A c q u i r e A E S I n f o                                               %
00176 %                                                                             %
00177 %                                                                             %
00178 %                                                                             %
00179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00180 %
00181 %  AcquireAESInfo() allocate the AESInfo structure.
00182 %
00183 %  The format of the AcquireAESInfo method is:
00184 %
00185 %      AESInfo *AcquireAESInfo(void)
00186 %
00187 */
00188 static AESInfo *AcquireAESInfo(void)
00189 {
00190   AESInfo
00191     *aes_info;
00192 
00193   aes_info=(AESInfo *) AcquireMagickMemory(sizeof(*aes_info));
00194   if (aes_info == (AESInfo *) NULL)
00195     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00196   (void) ResetMagickMemory(aes_info,0,sizeof(*aes_info));
00197   aes_info->blocksize=AESBlocksize;
00198   aes_info->key=AcquireStringInfo(32);
00199   aes_info->encipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
00200     *aes_info->encipher_key));
00201   aes_info->decipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
00202     *aes_info->decipher_key));
00203   if ((aes_info->key == (StringInfo *) NULL) ||
00204       (aes_info->encipher_key == (unsigned int *) NULL) ||
00205       (aes_info->decipher_key == (unsigned int *) NULL))
00206     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00207   aes_info->timestamp=(ssize_t) time(0);
00208   aes_info->signature=MagickSignature;
00209   return(aes_info);
00210 }
00211 
00212 /*
00213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00214 %                                                                             %
00215 %                                                                             %
00216 %                                                                             %
00217 %   D e s t r o y A E S I n f o                                               %
00218 %                                                                             %
00219 %                                                                             %
00220 %                                                                             %
00221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00222 %
00223 %  DestroyAESInfo() zeros memory associated with the AESInfo structure.
00224 %
00225 %  The format of the DestroyAESInfo method is:
00226 %
00227 %      AESInfo *DestroyAESInfo(AESInfo *aes_info)
00228 %
00229 %  A description of each parameter follows:
00230 %
00231 %    o aes_info: the cipher context.
00232 %
00233 */
00234 static AESInfo *DestroyAESInfo(AESInfo *aes_info)
00235 {
00236   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00237   assert(aes_info != (AESInfo *) NULL);
00238   assert(aes_info->signature == MagickSignature);
00239   if (aes_info->decipher_key != (unsigned int *) NULL)
00240     aes_info->decipher_key=(unsigned int *) RelinquishMagickMemory(
00241       aes_info->decipher_key);
00242   if (aes_info->encipher_key != (unsigned int *) NULL)
00243     aes_info->encipher_key=(unsigned int *) RelinquishMagickMemory(
00244       aes_info->encipher_key);
00245   if (aes_info->key != (StringInfo *) NULL)
00246     aes_info->key=DestroyStringInfo(aes_info->key);
00247   aes_info->signature=(~MagickSignature);
00248   aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
00249   return(aes_info);
00250 }
00251 
00252 /*
00253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00254 %                                                                             %
00255 %                                                                             %
00256 %                                                                             %
00257 %   E n c i p h e r A E S B l o c k                                           %
00258 %                                                                             %
00259 %                                                                             %
00260 %                                                                             %
00261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00262 %
00263 %  EncipherAESBlock() enciphers a single block of plaintext to produce a block
00264 %  of ciphertext.
00265 %
00266 %  The format of the EncipherAESBlock method is:
00267 %
00268 %      void EncipherAES(AESInfo *aes_info,const unsigned char *plaintext,
00269 %        unsigned char *ciphertext)
00270 %
00271 %  A description of each parameter follows:
00272 %
00273 %    o aes_info: the cipher context.
00274 %
00275 %    o plaintext: the plain text.
00276 %
00277 %    o ciphertext: the cipher text.
00278 %
00279 */
00280 
00281 static inline void AddRoundKey(const unsigned int *ciphertext,
00282   const unsigned int *key,unsigned int *plaintext)
00283 {
00284   register ssize_t
00285     i;
00286 
00287   /*
00288     Xor corresponding text input and round key input bytes.
00289   */
00290   for (i=0; i < 4; i++)
00291     plaintext[i]=key[i] ^ ciphertext[i];
00292 }
00293 
00294 static inline unsigned char ByteMultiply(const unsigned char alpha,
00295   const unsigned char beta)
00296 {
00297   /*
00298     Byte multiply two elements of GF(2^m) (mix columns and inverse mix columns).
00299   */
00300   if ((alpha == 0) || (beta == 0))
00301     return(0);
00302   return(InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
00303 }
00304 
00305 static inline unsigned int ByteSubTransform(unsigned int x,
00306   unsigned char *s_box)
00307 {
00308   unsigned int
00309     key;
00310 
00311   /*
00312     Non-linear layer resists differential and linear cryptoanalysis attacks.
00313   */
00314   key=(s_box[x & 0xff]) | (s_box[(x >> 8) & 0xff] << 8) |
00315     (s_box[(x >> 16) & 0xff] << 16) | (s_box[(x >> 24) & 0xff] << 24);
00316   return(key);
00317 }
00318 
00319 static void FinalizeRoundKey(const unsigned int *ciphertext,
00320   const unsigned int *key,unsigned char *plaintext)
00321 {
00322   register unsigned char
00323     *p;
00324 
00325   register unsigned int
00326     i,
00327     j;
00328 
00329   unsigned int
00330     value;
00331 
00332   /*
00333     The round key is XORed with the result of the mix-column transformation.
00334   */
00335   p=plaintext;
00336   for (i=0; i < 4; i++)
00337   {
00338     value=ciphertext[i] ^ key[i];
00339     for (j=0; j < 4; j++)
00340       *p++=(unsigned char) ((value >> (8*j)) & 0xff);
00341   }
00342   /*
00343     Reset registers.
00344   */
00345   value=0;
00346 }
00347 
00348 static void InitializeRoundKey(const unsigned char *ciphertext,
00349   const unsigned int *key,unsigned int *plaintext)
00350 {
00351   register const unsigned char
00352     *p;
00353 
00354   register unsigned int
00355     i,
00356     j;
00357 
00358   unsigned int
00359     value;
00360 
00361   p=ciphertext;
00362   for (i=0; i < 4; i++)
00363   {
00364     value=0;
00365     for (j=0; j < 4; j++)
00366       value|=(*p++ << (8*j));
00367     plaintext[i]=key[i] ^ value;
00368   }
00369   /*
00370     Reset registers.
00371   */
00372   value=0;
00373 }
00374 
00375 static inline unsigned int RotateLeft(const unsigned int x)
00376 {
00377   return(((x << 8) | ((x >> 24) & 0xff)));
00378 }
00379 
00380 static void EncipherAESBlock(AESInfo *aes_info,const unsigned char *plaintext,
00381   unsigned char *ciphertext)
00382 {
00383   register ssize_t
00384     i,
00385     j;
00386 
00387   static int
00388     map[4][4] =
00389     {
00390       { 0, 1, 2, 3 },
00391       { 1, 2, 3, 0 },
00392       { 2, 3, 0, 1 },
00393       { 3, 0, 1, 2 }
00394     };
00395 
00396   static unsigned int
00397     D[] =
00398     {
00399       0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
00400       0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
00401       0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
00402       0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
00403       0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
00404       0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
00405       0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
00406       0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
00407       0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
00408       0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
00409       0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
00410       0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
00411       0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
00412       0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
00413       0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
00414       0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
00415       0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
00416       0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
00417       0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
00418       0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
00419       0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
00420       0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
00421       0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
00422       0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
00423       0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
00424       0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
00425       0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
00426       0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
00427       0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
00428       0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
00429       0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
00430       0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
00431       0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
00432       0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
00433       0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
00434       0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
00435       0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
00436       0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
00437       0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
00438       0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
00439       0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
00440       0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
00441       0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
00442       0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
00443       0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
00444       0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
00445       0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
00446       0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
00447       0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
00448       0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
00449       0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
00450       0x3a16162cU
00451     };
00452 
00453   unsigned int
00454     alpha,
00455     key[4],
00456     text[4];
00457 
00458   /*
00459     Encipher one block.
00460   */
00461   (void) memset(text,0,sizeof(text));
00462   InitializeRoundKey(plaintext,aes_info->encipher_key,text);
00463   for (i=1; i < aes_info->rounds; i++)
00464   {
00465     /*
00466       Linear mixing step: cause diffusion of the bits over multiple rounds.
00467     */
00468     for (j=0; j < 4; j++)
00469       key[j]=D[text[j] & 0xff] ^
00470         RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
00471         RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
00472         RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
00473     AddRoundKey(key,aes_info->encipher_key+4*i,text);
00474   }
00475   for (i=0; i < 4; i++)
00476   {
00477     alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
00478       ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
00479     key[i]=ByteSubTransform(alpha,SBox);
00480   }
00481   FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
00482   /*
00483     Reset registers.
00484   */
00485   alpha=0;
00486   (void) ResetMagickMemory(key,0,sizeof(key));
00487   (void) ResetMagickMemory(text,0,sizeof(text));
00488 }
00489 
00490 /*
00491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00492 %                                                                             %
00493 %                                                                             %
00494 %                                                                             %
00495 %     P a s s k e y D e c i p h e r I m a g e                                 %
00496 %                                                                             %
00497 %                                                                             %
00498 %                                                                             %
00499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00500 %
00501 %  PasskeyDecipherImage() converts cipher pixels to plain pixels.
00502 %
00503 %  The format of the PasskeyDecipherImage method is:
00504 %
00505 %      MagickBooleanType PasskeyDecipherImage(Image *image,
00506 %        const StringInfo *passkey,ExceptionInfo *exception)
00507 %      MagickBooleanType DecipherImage(Image *image,const char *passphrase,
00508 %        ExceptionInfo *exception)
00509 %
00510 %  A description of each parameter follows:
00511 %
00512 %    o image: the image.
00513 %
00514 %    o passphrase: decipher cipher pixels with this passphrase.
00515 %
00516 %    o passkey: decrypt cipher pixels with this passkey.
00517 %
00518 %    o exception: return any errors or warnings in this structure.
00519 %
00520 */
00521 
00522 static inline size_t MagickMin(const size_t x,const size_t y)
00523 {
00524   if (x < y)
00525     return(x);
00526   return(y);
00527 }
00528 
00529 MagickExport MagickBooleanType DecipherImage(Image *image,
00530   const char *passphrase,ExceptionInfo *exception)
00531 {
00532   MagickBooleanType
00533     status;
00534 
00535   StringInfo
00536     *passkey;
00537 
00538   if (passphrase == (const char *) NULL)
00539     return(MagickTrue);
00540   passkey=StringToStringInfo(passphrase);
00541   if (passkey == (StringInfo *) NULL)
00542     return(MagickFalse);
00543   status=PasskeyDecipherImage(image,passkey,exception);
00544   passkey=DestroyStringInfo(passkey);
00545   return(status);
00546 }
00547 
00548 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
00549   const StringInfo *passkey,ExceptionInfo *exception)
00550 {
00551 #define DecipherImageTag  "Decipher/Image "
00552 
00553   AESInfo
00554     *aes_info;
00555 
00556   CacheView
00557     *image_view;
00558 
00559   const unsigned char
00560     *digest;
00561 
00562   MagickBooleanType
00563     proceed;
00564 
00565   QuantumInfo
00566     *quantum_info;
00567 
00568   QuantumType
00569     quantum_type;
00570 
00571   SignatureInfo
00572     *signature_info;
00573 
00574   register unsigned char
00575     *p;
00576 
00577   size_t
00578     length;
00579 
00580   ssize_t
00581     y;
00582 
00583   StringInfo
00584     *key,
00585     *nonce;
00586 
00587   unsigned char
00588     input_block[AESBlocksize],
00589     output_block[AESBlocksize],
00590     *pixels;
00591 
00592   /*
00593     Generate decipher key and nonce.
00594   */
00595   assert(image != (Image *) NULL);
00596   assert(image->signature == MagickSignature);
00597   if (image->debug != MagickFalse)
00598     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00599   assert(exception != (ExceptionInfo *) NULL);
00600   assert(exception->signature == MagickSignature);
00601   if (passkey == (const StringInfo *) NULL)
00602     return(MagickTrue);
00603   quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
00604   if (quantum_info == (QuantumInfo *) NULL)
00605     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00606       image->filename);
00607   aes_info=AcquireAESInfo();
00608   key=CloneStringInfo(passkey);
00609   if (key == (StringInfo *) NULL)
00610     {
00611       aes_info=DestroyAESInfo(aes_info);
00612       quantum_info=DestroyQuantumInfo(quantum_info);
00613       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00614         image->filename);
00615     }
00616   nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
00617   if (nonce == (StringInfo *) NULL)
00618     {
00619       key=DestroyStringInfo(key);
00620       aes_info=DestroyAESInfo(aes_info);
00621       quantum_info=DestroyQuantumInfo(quantum_info);
00622       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00623         image->filename);
00624     }
00625   SetAESKey(aes_info,key);
00626   key=DestroyStringInfo(key);
00627   signature_info=AcquireSignatureInfo();
00628   UpdateSignature(signature_info,nonce);
00629   SetStringInfoLength(nonce,sizeof(quantum_info->extent));
00630   SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
00631   UpdateSignature(signature_info,nonce);
00632   FinalizeSignature(signature_info);
00633   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00634   digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00635   (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
00636     GetSignatureDigestsize(signature_info))*sizeof(*input_block));
00637   nonce=DestroyStringInfo(nonce);
00638   signature_info=DestroySignatureInfo(signature_info);
00639   /*
00640     Convert cipher pixels to plain pixels.
00641   */
00642   quantum_type=GetQuantumType(image,exception);
00643   pixels=GetQuantumPixels(quantum_info);
00644   image_view=AcquireCacheView(image);
00645   for (y=0; y < (ssize_t) image->rows; y++)
00646   {
00647     register ssize_t
00648       x;
00649 
00650     register Quantum
00651       *restrict q;
00652 
00653     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
00654     if (q == (Quantum *) NULL)
00655       break;
00656     length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
00657       pixels,exception);
00658     p=pixels;
00659     for (x=0; x < (ssize_t) length; x++)
00660     {
00661       (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
00662         sizeof(*output_block));
00663       EncipherAESBlock(aes_info,output_block,output_block);
00664       (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
00665         sizeof(*input_block));
00666       input_block[AESBlocksize-1]=(*p);
00667       *p++^=(*output_block);
00668     }
00669     (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
00670       pixels,exception);
00671     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
00672       break;
00673     proceed=SetImageProgress(image,DecipherImageTag,(MagickOffsetType) y,
00674       image->rows);
00675     if (proceed == MagickFalse)
00676       break;
00677   }
00678   image_view=DestroyCacheView(image_view);
00679   (void) DeleteImageProperty(image,"cipher:type");
00680   (void) DeleteImageProperty(image,"cipher:mode");
00681   (void) DeleteImageProperty(image,"cipher:nonce");
00682   image->taint=MagickFalse;
00683   /*
00684     Free resources.
00685   */
00686   quantum_info=DestroyQuantumInfo(quantum_info);
00687   aes_info=DestroyAESInfo(aes_info);
00688   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00689   (void) ResetMagickMemory(output_block,0,sizeof(output_block));
00690   return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
00691 }
00692 
00693 /*
00694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00695 %                                                                             %
00696 %                                                                             %
00697 %                                                                             %
00698 %     P a s s k e y E n c i p h e r I m a g e                                 %
00699 %                                                                             %
00700 %                                                                             %
00701 %                                                                             %
00702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00703 %
00704 %  PasskeyEncipherImage() converts pixels to cipher-pixels.
00705 %
00706 %  The format of the PasskeyEncipherImage method is:
00707 %
00708 %      MagickBooleanType PasskeyEncipherImage(Image *image,
00709 %        const StringInfo *passkey,ExceptionInfo *exception)
00710 %      MagickBooleanType EncipherImage(Image *image,const char *passphrase,
00711 %        ExceptionInfo *exception)
00712 %
00713 %  A description of each parameter follows:
00714 %
00715 %    o image: the image.
00716 %
00717 %    o passphrase: encipher pixels with this passphrase.
00718 %
00719 %    o passkey: decrypt cipher pixels with this passkey.
00720 %
00721 %    o exception: return any errors or warnings in this structure.
00722 %
00723 */
00724 
00725 MagickExport MagickBooleanType EncipherImage(Image *image,
00726   const char *passphrase,ExceptionInfo *exception)
00727 {
00728   MagickBooleanType
00729     status;
00730 
00731   StringInfo
00732     *passkey;
00733 
00734   if (passphrase == (const char *) NULL)
00735     return(MagickTrue);
00736   passkey=StringToStringInfo(passphrase);
00737   if (passkey == (StringInfo *) NULL)
00738     return(MagickFalse);
00739   status=PasskeyEncipherImage(image,passkey,exception);
00740   passkey=DestroyStringInfo(passkey);
00741   return(status);
00742 }
00743 
00744 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
00745   const StringInfo *passkey,ExceptionInfo *exception)
00746 {
00747 #define EncipherImageTag  "Encipher/Image "
00748 
00749   AESInfo
00750     *aes_info;
00751 
00752   CacheView
00753     *image_view;
00754 
00755   char
00756     *signature;
00757 
00758   const unsigned char
00759     *digest;
00760 
00761   MagickBooleanType
00762     proceed;
00763 
00764   QuantumInfo
00765     *quantum_info;
00766 
00767   QuantumType
00768     quantum_type;
00769 
00770   register unsigned char
00771     *p;
00772 
00773   SignatureInfo
00774     *signature_info;
00775 
00776   size_t
00777     length;
00778 
00779   ssize_t
00780     y;
00781 
00782   StringInfo
00783     *key,
00784     *nonce;
00785 
00786   unsigned char
00787     input_block[AESBlocksize],
00788     output_block[AESBlocksize],
00789     *pixels;
00790 
00791   /*
00792     Generate encipher key and nonce.
00793   */
00794   assert(image != (Image *) NULL);
00795   assert(image->signature == MagickSignature);
00796   if (image->debug != MagickFalse)
00797     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00798   assert(exception != (ExceptionInfo *) NULL);
00799   assert(exception->signature == MagickSignature);
00800   if (passkey == (const StringInfo *) NULL)
00801     return(MagickTrue);
00802   if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
00803     return(MagickFalse);
00804   quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
00805   if (quantum_info == (QuantumInfo *) NULL)
00806     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00807       image->filename);
00808   aes_info=AcquireAESInfo();
00809   key=CloneStringInfo(passkey);
00810   if (key == (StringInfo *) NULL)
00811     {
00812       aes_info=DestroyAESInfo(aes_info);
00813       quantum_info=DestroyQuantumInfo(quantum_info);
00814       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00815         image->filename);
00816     }
00817   nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
00818   if (nonce == (StringInfo *) NULL)
00819     {
00820       key=DestroyStringInfo(key);
00821       aes_info=DestroyAESInfo(aes_info);
00822       quantum_info=DestroyQuantumInfo(quantum_info);
00823       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00824         image->filename);
00825     }
00826   SetAESKey(aes_info,key);
00827   key=DestroyStringInfo(key);
00828   signature_info=AcquireSignatureInfo();
00829   UpdateSignature(signature_info,nonce);
00830   SetStringInfoLength(nonce,sizeof(quantum_info->extent));
00831   SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
00832   UpdateSignature(signature_info,nonce);
00833   nonce=DestroyStringInfo(nonce);
00834   FinalizeSignature(signature_info);
00835   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00836   digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00837   (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
00838     GetSignatureDigestsize(signature_info))*sizeof(*input_block));
00839   signature=StringInfoToHexString(GetSignatureDigest(signature_info));
00840   (void) SetImageProperty(image,"cipher:type","AES",exception);
00841   (void) SetImageProperty(image,"cipher:mode","CFB",exception);
00842   (void) SetImageProperty(image,"cipher:nonce",signature,exception);
00843   signature=DestroyString(signature);
00844   signature_info=DestroySignatureInfo(signature_info);
00845   /*
00846     Convert plain pixels to cipher pixels.
00847   */
00848   quantum_type=GetQuantumType(image,exception);
00849   pixels=GetQuantumPixels(quantum_info);
00850   image_view=AcquireCacheView(image);
00851   for (y=0; y < (ssize_t) image->rows; y++)
00852   {
00853     register ssize_t
00854       x;
00855 
00856     register Quantum
00857       *restrict q;
00858 
00859     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
00860     if (q == (Quantum *) NULL)
00861       break;
00862     length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
00863       pixels,exception);
00864     p=pixels;
00865     for (x=0; x < (ssize_t) length; x++)
00866     {
00867       (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
00868         sizeof(*output_block));
00869       EncipherAESBlock(aes_info,output_block,output_block);
00870       *p^=(*output_block);
00871       (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
00872         sizeof(*input_block));
00873       input_block[AESBlocksize-1]=(*p++);
00874     }
00875     (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
00876       pixels,exception);
00877     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
00878       break;
00879     proceed=SetImageProgress(image,EncipherImageTag,(MagickOffsetType) y,
00880       image->rows);
00881     if (proceed == MagickFalse)
00882       break;
00883   }
00884   image_view=DestroyCacheView(image_view);
00885   image->taint=MagickFalse;
00886   /*
00887     Free resources.
00888   */
00889   quantum_info=DestroyQuantumInfo(quantum_info);
00890   aes_info=DestroyAESInfo(aes_info);
00891   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00892   (void) ResetMagickMemory(output_block,0,sizeof(output_block));
00893   return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
00894 }
00895 
00896 /*
00897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00898 %                                                                             %
00899 %                                                                             %
00900 %                                                                             %
00901 %   S e t A E S K e y                                                         %
00902 %                                                                             %
00903 %                                                                             %
00904 %                                                                             %
00905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00906 %
00907 %  SetAESKey() sets the key for the AES cipher.  The key length is specified
00908 %  in bits.  Valid values are 128, 192, or 256 requiring a key buffer length
00909 %  in bytes of 16, 24, and 32 respectively.
00910 %
00911 %  The format of the SetAESKey method is:
00912 %
00913 %      SetAESKey(AESInfo *aes_info,const StringInfo *key)
00914 %
00915 %  A description of each parameter follows:
00916 %
00917 %    o aes_info: the cipher context.
00918 %
00919 %    o key: the key.
00920 %
00921 */
00922 
00923 static inline void InverseAddRoundKey(const unsigned int *alpha,
00924   unsigned int *beta)
00925 {
00926   register unsigned int
00927     i,
00928     j;
00929 
00930   for (i=0; i < 4; i++)
00931   {
00932     beta[i]=0;
00933     for (j=0; j < 4; j++)
00934       beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
00935         ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
00936         ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
00937         ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
00938   }
00939 }
00940 
00941 static inline unsigned int XTime(unsigned char alpha)
00942 {
00943   unsigned char
00944     beta;
00945 
00946   beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
00947   alpha<<=1;
00948   alpha^=beta;
00949   return(alpha);
00950 }
00951 
00952 static inline unsigned int RotateRight(const unsigned int x)
00953 {
00954   return((x >> 8) | ((x & 0xff) << 24));
00955 }
00956 
00957 static void SetAESKey(AESInfo *aes_info,const StringInfo *key)
00958 {
00959   register ssize_t
00960     i;
00961 
00962   ssize_t
00963     bytes,
00964     n;
00965 
00966   unsigned char
00967     *datum;
00968 
00969   unsigned int
00970     alpha,
00971     beta;
00972 
00973   /*
00974     Determine the number of rounds based on the number of bits in key.
00975   */
00976   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00977   assert(aes_info != (AESInfo *) NULL);
00978   assert(aes_info->signature == MagickSignature);
00979   assert(key != (StringInfo *) NULL);
00980   n=4;
00981   aes_info->rounds=10;
00982   if ((8*GetStringInfoLength(key)) >= 256)
00983     {
00984       n=8;
00985       aes_info->rounds=14;
00986     }
00987   else
00988     if ((8*GetStringInfoLength(key)) >= 192)
00989       {
00990         n=6;
00991         aes_info->rounds=12;
00992       }
00993   /*
00994     Generate crypt key.
00995   */
00996   datum=GetStringInfoDatum(aes_info->key);
00997   (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
00998   (void) CopyMagickMemory(datum,GetStringInfoDatum(key),MagickMin(
00999     GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
01000   for (i=0; i < n; i++)
01001     aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) |
01002       (datum[4*i+2] << 16) | (datum[4*i+3] << 24);
01003   beta=1;
01004   bytes=(AESBlocksize/4)*(aes_info->rounds+1);
01005   for (i=n; i < bytes; i++)
01006   {
01007     alpha=aes_info->encipher_key[i-1];
01008     if ((i % n) == 0)
01009       {
01010         alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
01011         beta=XTime((unsigned char) (beta & 0xff));
01012       }
01013     else
01014       if ((n > 6) && ((i % n) == 4))
01015         alpha=ByteSubTransform(alpha,SBox);
01016     aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
01017   }
01018   /*
01019     Generate deciper key (in reverse order).
01020   */
01021   for (i=0; i < 4; i++)
01022   {
01023     aes_info->decipher_key[i]=aes_info->encipher_key[i];
01024     aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
01025   }
01026   for (i=4; i < (bytes-4); i+=4)
01027     InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
01028   /*
01029     Reset registers.
01030   */
01031   datum=GetStringInfoDatum(aes_info->key);
01032   (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
01033   alpha=0;
01034   beta=0;
01035 }
01036 #else
01037 
01038 /*
01039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01040 %                                                                             %
01041 %                                                                             %
01042 %                                                                             %
01043 %     P a s s k e y D e c i p h e r I m a g e                                 %
01044 %                                                                             %
01045 %                                                                             %
01046 %                                                                             %
01047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01048 %
01049 %  PasskeyDecipherImage() converts cipher pixels to plain pixels.
01050 %
01051 %  The format of the PasskeyDecipherImage method is:
01052 %
01053 %      MagickBooleanType PasskeyDecipherImage(Image *image,
01054 %        const StringInfo *passkey,ExceptionInfo *exception)
01055 %      MagickBooleanType DecipherImage(Image *image,const char *passphrase,
01056 %        ExceptionInfo *exception)
01057 %
01058 %  A description of each parameter follows:
01059 %
01060 %    o image: the image.
01061 %
01062 %    o passphrase: decipher cipher pixels with this passphrase.
01063 %
01064 %    o passkey: decrypt cipher pixels with this passkey.
01065 %
01066 %    o exception: return any errors or warnings in this structure.
01067 %
01068 */
01069 
01070 MagickExport MagickBooleanType DecipherImage(Image *image,
01071   const char *passphrase,ExceptionInfo *exception)
01072 {
01073   assert(image != (Image *) NULL);
01074   assert(image->signature == MagickSignature);
01075   if (image->debug != MagickFalse)
01076     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01077   assert(exception != (ExceptionInfo *) NULL);
01078   assert(exception->signature == MagickSignature);
01079   (void) passphrase;
01080   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01081 }
01082 
01083 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
01084   const StringInfo *passkey,ExceptionInfo *exception)
01085 {
01086   assert(image != (Image *) NULL);
01087   assert(image->signature == MagickSignature);
01088   if (image->debug != MagickFalse)
01089     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01090   assert(exception != (ExceptionInfo *) NULL);
01091   assert(exception->signature == MagickSignature);
01092   (void) passkey;
01093   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01094 }
01095 
01096 /*
01097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01098 %                                                                             %
01099 %                                                                             %
01100 %                                                                             %
01101 %     P a s s k e y E n c i p h e r I m a g e                                 %
01102 %                                                                             %
01103 %                                                                             %
01104 %                                                                             %
01105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01106 %
01107 %  PasskeyEncipherImage() converts pixels to cipher-pixels.
01108 %
01109 %  The format of the PasskeyEncipherImage method is:
01110 %
01111 %      MagickBooleanType PasskeyEncipherImage(Image *image,
01112 %        const StringInfo *passkey,ExceptionInfo *exception)
01113 %      MagickBooleanType EncipherImage(Image *image,const char *passphrase,
01114 %        ExceptionInfo *exception)
01115 %
01116 %  A description of each parameter follows:
01117 %
01118 %    o passphrase: decipher cipher pixels with this passphrase.
01119 %
01120 %    o passkey: decrypt cipher pixels with this passkey.
01121 %
01122 %    o exception: return any errors or warnings in this structure.
01123 %
01124 */
01125 
01126 MagickExport MagickBooleanType EncipherImage(Image *image,
01127   const char *passphrase,ExceptionInfo *exception)
01128 {
01129   assert(image != (Image *) NULL);
01130   assert(image->signature == MagickSignature);
01131   if (image->debug != MagickFalse)
01132     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01133   assert(exception != (ExceptionInfo *) NULL);
01134   assert(exception->signature == MagickSignature);
01135   (void) passphrase;
01136   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01137 }
01138 
01139 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
01140   const StringInfo *passkey,ExceptionInfo *exception)
01141 {
01142   assert(image != (Image *) NULL);
01143   assert(image->signature == MagickSignature);
01144   if (image->debug != MagickFalse)
01145     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01146   assert(exception != (ExceptionInfo *) NULL);
01147   assert(exception->signature == MagickSignature);
01148   (void) passkey;
01149   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01150 }
01151 #endif