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