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