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-2009 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 "magick/studio.h"
00042 #include "magick/cache.h"
00043 #include "magick/cipher.h"
00044 #include "magick/exception.h"
00045 #include "magick/exception-private.h"
00046 #include "magick/hashmap.h"
00047 #include "magick/image.h"
00048 #include "magick/image-private.h"
00049 #include "magick/list.h"
00050 #include "magick/memory_.h"
00051 #include "magick/monitor.h"
00052 #include "magick/monitor-private.h"
00053 #include "magick/property.h"
00054 #include "magick/quantum-private.h"
00055 #include "magick/registry.h"
00056 #include "magick/semaphore.h"
00057 #include "magick/signature-private.h"
00058 #include "magick/splay-tree.h"
00059 #include "magick/statistic.h"
00060 #include "magick/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   long
00082     rounds,
00083     timestamp;
00084 
00085   unsigned long
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=(long) 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 long
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++=(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 long
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   const unsigned char
00557     *digest;
00558 
00559   IndexPacket
00560     *indexes;
00561 
00562   long
00563     y;
00564 
00565   MagickBooleanType
00566     proceed;
00567 
00568   QuantumInfo
00569     *quantum_info;
00570 
00571   QuantumType
00572     quantum_type;
00573 
00574   SignatureInfo
00575     *signature_info;
00576 
00577   register unsigned char
00578     *p;
00579 
00580   size_t
00581     length;
00582 
00583   StringInfo
00584     *key,
00585     *nonce;
00586 
00587   unsigned char
00588     input_block[AESBlocksize],
00589     output_block[AESBlocksize],
00590     *pixels;
00591 
00592   CacheView
00593     *image_view;
00594 
00595   /*
00596     Generate decipher key and nonce.
00597   */
00598   assert(image != (Image *) NULL);
00599   assert(image->signature == MagickSignature);
00600   if (image->debug != MagickFalse)
00601     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00602   assert(exception != (ExceptionInfo *) NULL);
00603   assert(exception->signature == MagickSignature);
00604   if (passkey == (const StringInfo *) NULL)
00605     return(MagickTrue);
00606   quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
00607   if (quantum_info == (QuantumInfo *) NULL)
00608     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00609       image->filename);
00610   aes_info=AcquireAESInfo();
00611   key=CloneStringInfo(passkey);
00612   if (key == (StringInfo *) NULL)
00613     {
00614       aes_info=DestroyAESInfo(aes_info);
00615       quantum_info=DestroyQuantumInfo(quantum_info);
00616       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00617         image->filename);
00618     }
00619   nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
00620   if (nonce == (StringInfo *) NULL)
00621     {
00622       key=DestroyStringInfo(key);
00623       aes_info=DestroyAESInfo(aes_info);
00624       quantum_info=DestroyQuantumInfo(quantum_info);
00625       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00626         image->filename);
00627     }
00628   SetAESKey(aes_info,key);
00629   key=DestroyStringInfo(key);
00630   signature_info=AcquireSignatureInfo();
00631   UpdateSignature(signature_info,nonce);
00632   SetStringInfoLength(nonce,sizeof(quantum_info->extent));
00633   SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
00634   UpdateSignature(signature_info,nonce);
00635   FinalizeSignature(signature_info);
00636   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00637   digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00638   (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
00639     GetSignatureDigestsize(signature_info))*sizeof(*input_block));
00640   nonce=DestroyStringInfo(nonce);
00641   signature_info=DestroySignatureInfo(signature_info);
00642   /*
00643     Convert cipher pixels to plain pixels.
00644   */
00645   quantum_type=GetQuantumType(image,exception);
00646   pixels=GetQuantumPixels(quantum_info);
00647   image_view=AcquireCacheView(image);
00648   for (y=0; y < (long) image->rows; y++)
00649   {
00650     register long
00651       x;
00652 
00653     register PixelPacket
00654       *__restrict q;
00655 
00656     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
00657     if (q == (PixelPacket *) NULL)
00658       break;
00659     indexes=GetCacheViewAuthenticIndexQueue(image_view);
00660     length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
00661       pixels,exception);
00662     p=pixels;
00663     for (x=0; x < (long) length; x++)
00664     {
00665       (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
00666         sizeof(*output_block));
00667       EncipherAESBlock(aes_info,output_block,output_block);
00668       (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
00669         sizeof(*input_block));
00670       input_block[AESBlocksize-1]=(*p);
00671       *p++^=(*output_block);
00672     }
00673     (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
00674       pixels,exception);
00675     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
00676       break;
00677     proceed=SetImageProgress(image,DecipherImageTag,y,image->rows);
00678     if (proceed == MagickFalse)
00679       break;
00680   }
00681   image_view=DestroyCacheView(image_view);
00682   (void) DeleteImageProperty(image,"cipher:type");
00683   (void) DeleteImageProperty(image,"cipher:mode");
00684   (void) DeleteImageProperty(image,"cipher:nonce");
00685   image->taint=MagickFalse;
00686   /*
00687     Free resources.
00688   */
00689   quantum_info=DestroyQuantumInfo(quantum_info);
00690   aes_info=DestroyAESInfo(aes_info);
00691   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00692   (void) ResetMagickMemory(output_block,0,sizeof(output_block));
00693   return(y == (long) image->rows ? MagickTrue : MagickFalse);
00694 }
00695 
00696 /*
00697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00698 %                                                                             %
00699 %                                                                             %
00700 %                                                                             %
00701 %     P a s s k e y E n c i p h e r I m a g e                                 %
00702 %                                                                             %
00703 %                                                                             %
00704 %                                                                             %
00705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00706 %
00707 %  PasskeyEncipherImage() converts pixels to cipher-pixels.
00708 %
00709 %  The format of the PasskeyEncipherImage method is:
00710 %
00711 %      MagickBooleanType PasskeyEncipherImage(Image *image,
00712 %        const StringInfo *passkey,ExceptionInfo *exception)
00713 %      MagickBooleanType EncipherImage(Image *image,const char *passphrase,
00714 %        ExceptionInfo *exception)
00715 %
00716 %  A description of each parameter follows:
00717 %
00718 %    o image: the image.
00719 %
00720 %    o passphrase: encipher pixels with this passphrase.
00721 %
00722 %    o passkey: decrypt cipher pixels with this passkey.
00723 %
00724 %    o exception: return any errors or warnings in this structure.
00725 %
00726 */
00727 
00728 MagickExport MagickBooleanType EncipherImage(Image *image,
00729   const char *passphrase,ExceptionInfo *exception)
00730 {
00731   MagickBooleanType
00732     status;
00733 
00734   StringInfo
00735     *passkey;
00736 
00737   if (passphrase == (const char *) NULL)
00738     return(MagickTrue);
00739   passkey=StringToStringInfo(passphrase);
00740   if (passkey == (StringInfo *) NULL)
00741     return(MagickFalse);
00742   status=PasskeyEncipherImage(image,passkey,exception);
00743   passkey=DestroyStringInfo(passkey);
00744   return(status);
00745 }
00746 
00747 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
00748   const StringInfo *passkey,ExceptionInfo *exception)
00749 {
00750 #define EncipherImageTag  "Encipher/Image "
00751 
00752   AESInfo
00753     *aes_info;
00754 
00755   char
00756     *signature;
00757 
00758   const unsigned char
00759     *digest;
00760 
00761   IndexPacket
00762     *indexes;
00763 
00764   long
00765     y;
00766 
00767   MagickBooleanType
00768     proceed;
00769 
00770   QuantumInfo
00771     *quantum_info;
00772 
00773   QuantumType
00774     quantum_type;
00775 
00776   register unsigned char
00777     *p;
00778 
00779   SignatureInfo
00780     *signature_info;
00781 
00782   size_t
00783     length;
00784 
00785   StringInfo
00786     *key,
00787     *nonce;
00788 
00789   unsigned char
00790     input_block[AESBlocksize],
00791     output_block[AESBlocksize],
00792     *pixels;
00793 
00794   CacheView
00795     *image_view;
00796 
00797   /*
00798     Generate encipher key and nonce.
00799   */
00800   assert(image != (Image *) NULL);
00801   assert(image->signature == MagickSignature);
00802   if (image->debug != MagickFalse)
00803     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00804   assert(exception != (ExceptionInfo *) NULL);
00805   assert(exception->signature == MagickSignature);
00806   if (passkey == (const StringInfo *) NULL)
00807     return(MagickTrue);
00808   if (SetImageStorageClass(image,DirectClass) == MagickFalse)
00809     return(MagickFalse);
00810   quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
00811   if (quantum_info == (QuantumInfo *) NULL)
00812     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00813       image->filename);
00814   aes_info=AcquireAESInfo();
00815   key=CloneStringInfo(passkey);
00816   if (key == (StringInfo *) NULL)
00817     {
00818       aes_info=DestroyAESInfo(aes_info);
00819       quantum_info=DestroyQuantumInfo(quantum_info);
00820       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00821         image->filename);
00822     }
00823   nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
00824   if (nonce == (StringInfo *) NULL)
00825     {
00826       key=DestroyStringInfo(key);
00827       aes_info=DestroyAESInfo(aes_info);
00828       quantum_info=DestroyQuantumInfo(quantum_info);
00829       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00830         image->filename);
00831     }
00832   SetAESKey(aes_info,key);
00833   key=DestroyStringInfo(key);
00834   signature_info=AcquireSignatureInfo();
00835   UpdateSignature(signature_info,nonce);
00836   SetStringInfoLength(nonce,sizeof(quantum_info->extent));
00837   SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
00838   UpdateSignature(signature_info,nonce);
00839   nonce=DestroyStringInfo(nonce);
00840   FinalizeSignature(signature_info);
00841   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00842   digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00843   (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
00844     GetSignatureDigestsize(signature_info))*sizeof(*input_block));
00845   signature=StringInfoToHexString(GetSignatureDigest(signature_info));
00846   (void) SetImageProperty(image,"cipher:type","AES");
00847   (void) SetImageProperty(image,"cipher:mode","CFB");
00848   (void) SetImageProperty(image,"cipher:nonce",signature);
00849   signature=DestroyString(signature);
00850   signature_info=DestroySignatureInfo(signature_info);
00851   /*
00852     Convert plain pixels to cipher pixels.
00853   */
00854   quantum_type=GetQuantumType(image,exception);
00855   pixels=GetQuantumPixels(quantum_info);
00856   image_view=AcquireCacheView(image);
00857   for (y=0; y < (long) image->rows; y++)
00858   {
00859     register long
00860       x;
00861 
00862     register PixelPacket
00863       *__restrict q;
00864 
00865     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
00866     if (q == (PixelPacket *) NULL)
00867       break;
00868     indexes=GetCacheViewAuthenticIndexQueue(image_view);
00869     length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
00870       pixels,exception);
00871     p=pixels;
00872     for (x=0; x < (long) length; x++)
00873     {
00874       (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
00875         sizeof(*output_block));
00876       EncipherAESBlock(aes_info,output_block,output_block);
00877       *p^=(*output_block);
00878       (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
00879         sizeof(*input_block));
00880       input_block[AESBlocksize-1]=(*p++);
00881     }
00882     (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
00883       pixels,exception);
00884     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
00885       break;
00886     proceed=SetImageProgress(image,EncipherImageTag,y,image->rows);
00887     if (proceed == MagickFalse)
00888       break;
00889   }
00890   image_view=DestroyCacheView(image_view);
00891   image->taint=MagickFalse;
00892   /*
00893     Free resources.
00894   */
00895   quantum_info=DestroyQuantumInfo(quantum_info);
00896   aes_info=DestroyAESInfo(aes_info);
00897   (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00898   (void) ResetMagickMemory(output_block,0,sizeof(output_block));
00899   return(y == (long) image->rows ? MagickTrue : MagickFalse);
00900 }
00901 
00902 /*
00903 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00904 %                                                                             %
00905 %                                                                             %
00906 %                                                                             %
00907 %   S e t A E S K e y                                                         %
00908 %                                                                             %
00909 %                                                                             %
00910 %                                                                             %
00911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00912 %
00913 %  SetAESKey() sets the key for the AES cipher.  The key length is specified
00914 %  in bits.  Valid values are 128, 192, or 256 requiring a key buffer length
00915 %  in bytes of 16, 24, and 32 respectively.
00916 %
00917 %  The format of the SetAESKey method is:
00918 %
00919 %      SetAESKey(AESInfo *aes_info,const StringInfo *key)
00920 %
00921 %  A description of each parameter follows:
00922 %
00923 %    o aes_info: the cipher context.
00924 %
00925 %    o key: the key.
00926 %
00927 */
00928 
00929 static inline void InverseAddRoundKey(const unsigned int *alpha,
00930   unsigned int *beta)
00931 {
00932   register unsigned int
00933     i,
00934     j;
00935 
00936   for (i=0; i < 4; i++)
00937   {
00938     beta[i]=0;
00939     for (j=0; j < 4; j++)
00940       beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
00941         ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
00942         ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
00943         ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
00944   }
00945 }
00946 
00947 static inline unsigned int XTime(unsigned char alpha)
00948 {
00949   unsigned char
00950     beta;
00951 
00952   beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
00953   alpha<<=1;
00954   alpha^=beta;
00955   return(alpha);
00956 }
00957 
00958 static inline unsigned int RotateRight(const unsigned int x)
00959 {
00960   return((x >> 8) | ((x & 0xff) << 24));
00961 }
00962 
00963 static void SetAESKey(AESInfo *aes_info,const StringInfo *key)
00964 {
00965   long
00966     bytes,
00967     n;
00968 
00969   register long
00970     i;
00971 
00972   unsigned char
00973     *datum;
00974 
00975   unsigned int
00976     alpha,
00977     beta;
00978 
00979   /*
00980     Determine the number of rounds based on the number of bits in key.
00981   */
00982   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00983   assert(aes_info != (AESInfo *) NULL);
00984   assert(aes_info->signature == MagickSignature);
00985   assert(key != (StringInfo *) NULL);
00986   n=4;
00987   aes_info->rounds=10;
00988   if ((8*GetStringInfoLength(key)) >= 256)
00989     {
00990       n=8;
00991       aes_info->rounds=14;
00992     }
00993   else
00994     if ((8*GetStringInfoLength(key)) >= 192)
00995       {
00996         n=6;
00997         aes_info->rounds=12;
00998       }
00999   /*
01000     Generate crypt key.
01001   */
01002   datum=GetStringInfoDatum(aes_info->key);
01003   (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
01004   (void) CopyMagickMemory(datum,GetStringInfoDatum(key),MagickMin(
01005     GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
01006   for (i=0; i < n; i++)
01007     aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) |
01008       (datum[4*i+2] << 16) | (datum[4*i+3] << 24);
01009   beta=1;
01010   bytes=(AESBlocksize/4)*(aes_info->rounds+1);
01011   for (i=n; i < bytes; i++)
01012   {
01013     alpha=aes_info->encipher_key[i-1];
01014     if ((i % n) == 0)
01015       {
01016         alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
01017         beta=XTime((unsigned char) (beta & 0xff));
01018       }
01019     else
01020       if ((n > 6) && ((i % n) == 4))
01021         alpha=ByteSubTransform(alpha,SBox);
01022     aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
01023   }
01024   /*
01025     Generate deciper key (in reverse order).
01026   */
01027   for (i=0; i < 4; i++)
01028   {
01029     aes_info->decipher_key[i]=aes_info->encipher_key[i];
01030     aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
01031   }
01032   for (i=4; i < (bytes-4); i+=4)
01033     InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
01034   /*
01035     Reset registers.
01036   */
01037   datum=GetStringInfoDatum(aes_info->key);
01038   (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
01039   alpha=0;
01040   beta=0;
01041 }
01042 #else
01043 
01044 /*
01045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01046 %                                                                             %
01047 %                                                                             %
01048 %                                                                             %
01049 %     P a s s k e y D e c i p h e r I m a g e                                 %
01050 %                                                                             %
01051 %                                                                             %
01052 %                                                                             %
01053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01054 %
01055 %  PasskeyDecipherImage() converts cipher pixels to plain pixels.
01056 %
01057 %  The format of the PasskeyDecipherImage method is:
01058 %
01059 %      MagickBooleanType PasskeyDecipherImage(Image *image,
01060 %        const StringInfo *passkey,ExceptionInfo *exception)
01061 %      MagickBooleanType DecipherImage(Image *image,const char *passphrase,
01062 %        ExceptionInfo *exception)
01063 %
01064 %  A description of each parameter follows:
01065 %
01066 %    o image: the image.
01067 %
01068 %    o passphrase: decipher cipher pixels with this passphrase.
01069 %
01070 %    o passkey: decrypt cipher pixels with this passkey.
01071 %
01072 %    o exception: return any errors or warnings in this structure.
01073 %
01074 */
01075 
01076 MagickExport MagickBooleanType DecipherImage(Image *image,
01077   const char *passphrase,ExceptionInfo *exception)
01078 {
01079   assert(image != (Image *) NULL);
01080   assert(image->signature == MagickSignature);
01081   if (image->debug != MagickFalse)
01082     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01083   assert(exception != (ExceptionInfo *) NULL);
01084   assert(exception->signature == MagickSignature);
01085   (void) passphrase;
01086   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01087 }
01088 
01089 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
01090   const StringInfo *passkey,ExceptionInfo *exception)
01091 {
01092   assert(image != (Image *) NULL);
01093   assert(image->signature == MagickSignature);
01094   if (image->debug != MagickFalse)
01095     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01096   assert(exception != (ExceptionInfo *) NULL);
01097   assert(exception->signature == MagickSignature);
01098   (void) passkey;
01099   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01100 }
01101 
01102 /*
01103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01104 %                                                                             %
01105 %                                                                             %
01106 %                                                                             %
01107 %     P a s s k e y E n c i p h e r I m a g e                                 %
01108 %                                                                             %
01109 %                                                                             %
01110 %                                                                             %
01111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01112 %
01113 %  PasskeyEncipherImage() converts pixels to cipher-pixels.
01114 %
01115 %  The format of the PasskeyEncipherImage method is:
01116 %
01117 %      MagickBooleanType PasskeyEncipherImage(Image *image,
01118 %        const StringInfo *passkey,ExceptionInfo *exception)
01119 %      MagickBooleanType EncipherImage(Image *image,const char *passphrase,
01120 %        ExceptionInfo *exception)
01121 %
01122 %  A description of each parameter follows:
01123 %
01124 %    o passphrase: decipher cipher pixels with this passphrase.
01125 %
01126 %    o passkey: decrypt cipher pixels with this passkey.
01127 %
01128 %    o exception: return any errors or warnings in this structure.
01129 %
01130 */
01131 
01132 MagickExport MagickBooleanType EncipherImage(Image *image,
01133   const char *passphrase,ExceptionInfo *exception)
01134 {
01135   assert(image != (Image *) NULL);
01136   assert(image->signature == MagickSignature);
01137   if (image->debug != MagickFalse)
01138     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01139   assert(exception != (ExceptionInfo *) NULL);
01140   assert(exception->signature == MagickSignature);
01141   (void) passphrase;
01142   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01143 }
01144 
01145 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
01146   const StringInfo *passkey,ExceptionInfo *exception)
01147 {
01148   assert(image != (Image *) NULL);
01149   assert(image->signature == MagickSignature);
01150   if (image->debug != MagickFalse)
01151     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01152   assert(exception != (ExceptionInfo *) NULL);
01153   assert(exception->signature == MagickSignature);
01154   (void) passkey;
01155   ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01156 }
01157 #endif

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1