2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % CCCC IIIII PPPP H H EEEEE RRRR %
7 % C I PPPP HHHHH EEE RRRR %
9 % CCCC IIIII P H H EEEEE R R %
12 % MagickCore Cipher Methods %
19 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
25 % http://www.imagemagick.org/script/license.php %
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. %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 #include "MagickCore/studio.h"
42 #include "MagickCore/cache.h"
43 #include "MagickCore/cipher.h"
44 #include "MagickCore/exception.h"
45 #include "MagickCore/exception-private.h"
46 #include "MagickCore/hashmap.h"
47 #include "MagickCore/image.h"
48 #include "MagickCore/image-private.h"
49 #include "MagickCore/list.h"
50 #include "MagickCore/memory_.h"
51 #include "MagickCore/monitor.h"
52 #include "MagickCore/monitor-private.h"
53 #include "MagickCore/property.h"
54 #include "MagickCore/quantum-private.h"
55 #include "MagickCore/registry.h"
56 #include "MagickCore/semaphore.h"
57 #include "MagickCore/signature-private.h"
58 #include "MagickCore/splay-tree.h"
59 #include "MagickCore/statistic.h"
60 #include "MagickCore/string_.h"
62 #if defined(MAGICKCORE_CIPHER_SUPPORT)
66 #define AESBlocksize 16
71 typedef struct _AESInfo
95 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248,
96 19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10,
97 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190,
98 217, 112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204,
99 79, 209, 104, 184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59,
100 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208,
101 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196,
102 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
103 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32,
104 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86,
105 250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237,
106 44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126,
107 130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35,
108 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99,
109 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, 69, 207,
110 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
111 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242,
112 13, 23, 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180,
117 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238,
118 223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200,
119 248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228,
120 166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36,
121 18, 240, 130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208,
122 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253, 48,
123 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110,
124 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
125 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115,
126 167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213,
127 231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245, 89, 203,
128 95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236,
129 216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96,
130 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144,
131 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, 83, 57,
132 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
133 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153,
134 227, 165, 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128,
139 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215,
140 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175,
141 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
142 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154,
143 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
144 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237,
145 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239,
146 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
147 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255,
148 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
149 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238,
150 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92,
151 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213,
152 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46,
153 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
154 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
155 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85,
156 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15,
161 Forward declarations.
164 *DestroyAESInfo(AESInfo *);
167 EncipherAESBlock(AESInfo *,const unsigned char *,unsigned char *),
168 SetAESKey(AESInfo *,const StringInfo *);
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175 % A c q u i r e A E S I n f o %
179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
181 % AcquireAESInfo() allocate the AESInfo structure.
183 % The format of the AcquireAESInfo method is:
185 % AESInfo *AcquireAESInfo(void)
188 static AESInfo *AcquireAESInfo(void)
193 aes_info=(AESInfo *) AcquireMagickMemory(sizeof(*aes_info));
194 if (aes_info == (AESInfo *) NULL)
195 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
196 (void) ResetMagickMemory(aes_info,0,sizeof(*aes_info));
197 aes_info->blocksize=AESBlocksize;
198 aes_info->key=AcquireStringInfo(32);
199 aes_info->encipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
200 *aes_info->encipher_key));
201 aes_info->decipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
202 *aes_info->decipher_key));
203 if ((aes_info->key == (StringInfo *) NULL) ||
204 (aes_info->encipher_key == (unsigned int *) NULL) ||
205 (aes_info->decipher_key == (unsigned int *) NULL))
206 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
207 aes_info->timestamp=(ssize_t) time(0);
208 aes_info->signature=MagickSignature;
213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217 % D e s t r o y A E S I n f o %
221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223 % DestroyAESInfo() zeros memory associated with the AESInfo structure.
225 % The format of the DestroyAESInfo method is:
227 % AESInfo *DestroyAESInfo(AESInfo *aes_info)
229 % A description of each parameter follows:
231 % o aes_info: the cipher context.
234 static AESInfo *DestroyAESInfo(AESInfo *aes_info)
236 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
237 assert(aes_info != (AESInfo *) NULL);
238 assert(aes_info->signature == MagickSignature);
239 if (aes_info->decipher_key != (unsigned int *) NULL)
240 aes_info->decipher_key=(unsigned int *) RelinquishMagickMemory(
241 aes_info->decipher_key);
242 if (aes_info->encipher_key != (unsigned int *) NULL)
243 aes_info->encipher_key=(unsigned int *) RelinquishMagickMemory(
244 aes_info->encipher_key);
245 if (aes_info->key != (StringInfo *) NULL)
246 aes_info->key=DestroyStringInfo(aes_info->key);
247 aes_info->signature=(~MagickSignature);
248 aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257 % E n c i p h e r A E S B l o c k %
261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
263 % EncipherAESBlock() enciphers a single block of plaintext to produce a block
266 % The format of the EncipherAESBlock method is:
268 % void EncipherAES(AESInfo *aes_info,const unsigned char *plaintext,
269 % unsigned char *ciphertext)
271 % A description of each parameter follows:
273 % o aes_info: the cipher context.
275 % o plaintext: the plain text.
277 % o ciphertext: the cipher text.
281 static inline void AddRoundKey(const unsigned int *ciphertext,
282 const unsigned int *key,unsigned int *plaintext)
288 Xor corresponding text input and round key input bytes.
290 for (i=0; i < 4; i++)
291 plaintext[i]=key[i] ^ ciphertext[i];
294 static inline unsigned char ByteMultiply(const unsigned char alpha,
295 const unsigned char beta)
298 Byte multiply two elements of GF(2^m) (mix columns and inverse mix columns).
300 if ((alpha == 0) || (beta == 0))
302 return(InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
305 static inline unsigned int ByteSubTransform(unsigned int x,
306 unsigned char *s_box)
312 Non-linear layer resists differential and linear cryptoanalysis attacks.
314 key=(s_box[x & 0xff]) | (s_box[(x >> 8) & 0xff] << 8) |
315 (s_box[(x >> 16) & 0xff] << 16) | (s_box[(x >> 24) & 0xff] << 24);
319 static void FinalizeRoundKey(const unsigned int *ciphertext,
320 const unsigned int *key,unsigned char *plaintext)
322 register unsigned char
325 register unsigned int
333 The round key is XORed with the result of the mix-column transformation.
336 for (i=0; i < 4; i++)
338 value=ciphertext[i] ^ key[i];
339 for (j=0; j < 4; j++)
340 *p++=(unsigned char) ((value >> (8*j)) & 0xff);
348 static void InitializeRoundKey(const unsigned char *ciphertext,
349 const unsigned int *key,unsigned int *plaintext)
351 register const unsigned char
354 register unsigned int
362 for (i=0; i < 4; i++)
365 for (j=0; j < 4; j++)
366 value|=(*p++ << (8*j));
367 plaintext[i]=key[i] ^ value;
375 static inline unsigned int RotateLeft(const unsigned int x)
377 return(((x << 8) | ((x >> 24) & 0xff)));
380 static void EncipherAESBlock(AESInfo *aes_info,const unsigned char *plaintext,
381 unsigned char *ciphertext)
399 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
400 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
401 0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
402 0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
403 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
404 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
405 0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
406 0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
407 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
408 0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
409 0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
410 0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
411 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
412 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
413 0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
414 0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
415 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
416 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
417 0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
418 0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
419 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
420 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
421 0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
422 0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
423 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
424 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
425 0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
426 0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
427 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
428 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
429 0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
430 0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
431 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
432 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
433 0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
434 0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
435 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
436 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
437 0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
438 0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
439 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
440 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
441 0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
442 0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
443 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
444 0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
445 0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
446 0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
447 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
448 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
449 0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
461 (void) memset(text,0,sizeof(text));
462 InitializeRoundKey(plaintext,aes_info->encipher_key,text);
463 for (i=1; i < aes_info->rounds; i++)
466 Linear mixing step: cause diffusion of the bits over multiple rounds.
468 for (j=0; j < 4; j++)
469 key[j]=D[text[j] & 0xff] ^
470 RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
471 RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
472 RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
473 AddRoundKey(key,aes_info->encipher_key+4*i,text);
475 for (i=0; i < 4; i++)
477 alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
478 ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
479 key[i]=ByteSubTransform(alpha,SBox);
481 FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
486 (void) ResetMagickMemory(key,0,sizeof(key));
487 (void) ResetMagickMemory(text,0,sizeof(text));
491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
495 % P a s s k e y D e c i p h e r I m a g e %
499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
501 % PasskeyDecipherImage() converts cipher pixels to plain pixels.
503 % The format of the PasskeyDecipherImage method is:
505 % MagickBooleanType PasskeyDecipherImage(Image *image,
506 % const StringInfo *passkey,ExceptionInfo *exception)
507 % MagickBooleanType DecipherImage(Image *image,const char *passphrase,
508 % ExceptionInfo *exception)
510 % A description of each parameter follows:
512 % o image: the image.
514 % o passphrase: decipher cipher pixels with this passphrase.
516 % o passkey: decrypt cipher pixels with this passkey.
518 % o exception: return any errors or warnings in this structure.
522 static inline size_t MagickMin(const size_t x,const size_t y)
529 MagickExport MagickBooleanType DecipherImage(Image *image,
530 const char *passphrase,ExceptionInfo *exception)
538 if (passphrase == (const char *) NULL)
540 passkey=StringToStringInfo(passphrase);
541 if (passkey == (StringInfo *) NULL)
543 status=PasskeyDecipherImage(image,passkey,exception);
544 passkey=DestroyStringInfo(passkey);
548 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
549 const StringInfo *passkey,ExceptionInfo *exception)
551 #define DecipherImageTag "Decipher/Image "
574 register unsigned char
588 input_block[AESBlocksize],
589 output_block[AESBlocksize],
593 Generate decipher key and nonce.
595 assert(image != (Image *) NULL);
596 assert(image->signature == MagickSignature);
597 if (image->debug != MagickFalse)
598 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
599 assert(exception != (ExceptionInfo *) NULL);
600 assert(exception->signature == MagickSignature);
601 if (passkey == (const StringInfo *) NULL)
603 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
604 if (quantum_info == (QuantumInfo *) NULL)
605 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
607 aes_info=AcquireAESInfo();
608 key=CloneStringInfo(passkey);
609 if (key == (StringInfo *) NULL)
611 aes_info=DestroyAESInfo(aes_info);
612 quantum_info=DestroyQuantumInfo(quantum_info);
613 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
616 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
617 if (nonce == (StringInfo *) NULL)
619 key=DestroyStringInfo(key);
620 aes_info=DestroyAESInfo(aes_info);
621 quantum_info=DestroyQuantumInfo(quantum_info);
622 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
625 SetAESKey(aes_info,key);
626 key=DestroyStringInfo(key);
627 signature_info=AcquireSignatureInfo();
628 UpdateSignature(signature_info,nonce);
629 SetStringInfoLength(nonce,sizeof(quantum_info->extent));
630 SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
631 UpdateSignature(signature_info,nonce);
632 FinalizeSignature(signature_info);
633 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
634 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
635 (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
636 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
637 nonce=DestroyStringInfo(nonce);
638 signature_info=DestroySignatureInfo(signature_info);
640 Convert cipher pixels to plain pixels.
642 quantum_type=GetQuantumType(image,exception);
643 pixels=GetQuantumPixels(quantum_info);
644 image_view=AcquireCacheView(image);
645 for (y=0; y < (ssize_t) image->rows; y++)
653 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
654 if (q == (Quantum *) NULL)
656 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
659 for (x=0; x < (ssize_t) length; x++)
661 (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
662 sizeof(*output_block));
663 EncipherAESBlock(aes_info,output_block,output_block);
664 (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
665 sizeof(*input_block));
666 input_block[AESBlocksize-1]=(*p);
667 *p++^=(*output_block);
669 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
671 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
673 proceed=SetImageProgress(image,DecipherImageTag,(MagickOffsetType) y,
675 if (proceed == MagickFalse)
678 image_view=DestroyCacheView(image_view);
679 (void) DeleteImageProperty(image,"cipher:type");
680 (void) DeleteImageProperty(image,"cipher:mode");
681 (void) DeleteImageProperty(image,"cipher:nonce");
682 image->taint=MagickFalse;
686 quantum_info=DestroyQuantumInfo(quantum_info);
687 aes_info=DestroyAESInfo(aes_info);
688 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
689 (void) ResetMagickMemory(output_block,0,sizeof(output_block));
690 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
698 % P a s s k e y E n c i p h e r I m a g e %
702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704 % PasskeyEncipherImage() converts pixels to cipher-pixels.
706 % The format of the PasskeyEncipherImage method is:
708 % MagickBooleanType PasskeyEncipherImage(Image *image,
709 % const StringInfo *passkey,ExceptionInfo *exception)
710 % MagickBooleanType EncipherImage(Image *image,const char *passphrase,
711 % ExceptionInfo *exception)
713 % A description of each parameter follows:
715 % o image: the image.
717 % o passphrase: encipher pixels with this passphrase.
719 % o passkey: decrypt cipher pixels with this passkey.
721 % o exception: return any errors or warnings in this structure.
725 MagickExport MagickBooleanType EncipherImage(Image *image,
726 const char *passphrase,ExceptionInfo *exception)
734 if (passphrase == (const char *) NULL)
736 passkey=StringToStringInfo(passphrase);
737 if (passkey == (StringInfo *) NULL)
739 status=PasskeyEncipherImage(image,passkey,exception);
740 passkey=DestroyStringInfo(passkey);
744 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
745 const StringInfo *passkey,ExceptionInfo *exception)
747 #define EncipherImageTag "Encipher/Image "
770 register unsigned char
787 input_block[AESBlocksize],
788 output_block[AESBlocksize],
792 Generate encipher key and nonce.
794 assert(image != (Image *) NULL);
795 assert(image->signature == MagickSignature);
796 if (image->debug != MagickFalse)
797 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
798 assert(exception != (ExceptionInfo *) NULL);
799 assert(exception->signature == MagickSignature);
800 if (passkey == (const StringInfo *) NULL)
802 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
804 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
805 if (quantum_info == (QuantumInfo *) NULL)
806 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
808 aes_info=AcquireAESInfo();
809 key=CloneStringInfo(passkey);
810 if (key == (StringInfo *) NULL)
812 aes_info=DestroyAESInfo(aes_info);
813 quantum_info=DestroyQuantumInfo(quantum_info);
814 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
817 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
818 if (nonce == (StringInfo *) NULL)
820 key=DestroyStringInfo(key);
821 aes_info=DestroyAESInfo(aes_info);
822 quantum_info=DestroyQuantumInfo(quantum_info);
823 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
826 SetAESKey(aes_info,key);
827 key=DestroyStringInfo(key);
828 signature_info=AcquireSignatureInfo();
829 UpdateSignature(signature_info,nonce);
830 SetStringInfoLength(nonce,sizeof(quantum_info->extent));
831 SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
832 UpdateSignature(signature_info,nonce);
833 nonce=DestroyStringInfo(nonce);
834 FinalizeSignature(signature_info);
835 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
836 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
837 (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
838 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
839 signature=StringInfoToHexString(GetSignatureDigest(signature_info));
840 (void) SetImageProperty(image,"cipher:type","AES");
841 (void) SetImageProperty(image,"cipher:mode","CFB");
842 (void) SetImageProperty(image,"cipher:nonce",signature);
843 signature=DestroyString(signature);
844 signature_info=DestroySignatureInfo(signature_info);
846 Convert plain pixels to cipher pixels.
848 quantum_type=GetQuantumType(image,exception);
849 pixels=GetQuantumPixels(quantum_info);
850 image_view=AcquireCacheView(image);
851 for (y=0; y < (ssize_t) image->rows; y++)
859 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
860 if (q == (Quantum *) NULL)
862 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
865 for (x=0; x < (ssize_t) length; x++)
867 (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
868 sizeof(*output_block));
869 EncipherAESBlock(aes_info,output_block,output_block);
871 (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
872 sizeof(*input_block));
873 input_block[AESBlocksize-1]=(*p++);
875 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
877 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
879 proceed=SetImageProgress(image,EncipherImageTag,(MagickOffsetType) y,
881 if (proceed == MagickFalse)
884 image_view=DestroyCacheView(image_view);
885 image->taint=MagickFalse;
889 quantum_info=DestroyQuantumInfo(quantum_info);
890 aes_info=DestroyAESInfo(aes_info);
891 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
892 (void) ResetMagickMemory(output_block,0,sizeof(output_block));
893 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901 % S e t A E S K e y %
905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
907 % SetAESKey() sets the key for the AES cipher. The key length is specified
908 % in bits. Valid values are 128, 192, or 256 requiring a key buffer length
909 % in bytes of 16, 24, and 32 respectively.
911 % The format of the SetAESKey method is:
913 % SetAESKey(AESInfo *aes_info,const StringInfo *key)
915 % A description of each parameter follows:
917 % o aes_info: the cipher context.
923 static inline void InverseAddRoundKey(const unsigned int *alpha,
926 register unsigned int
930 for (i=0; i < 4; i++)
933 for (j=0; j < 4; j++)
934 beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
935 ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
936 ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
937 ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
941 static inline unsigned int XTime(unsigned char alpha)
946 beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
952 static inline unsigned int RotateRight(const unsigned int x)
954 return((x >> 8) | ((x & 0xff) << 24));
957 static void SetAESKey(AESInfo *aes_info,const StringInfo *key)
974 Determine the number of rounds based on the number of bits in key.
976 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
977 assert(aes_info != (AESInfo *) NULL);
978 assert(aes_info->signature == MagickSignature);
979 assert(key != (StringInfo *) NULL);
982 if ((8*GetStringInfoLength(key)) >= 256)
988 if ((8*GetStringInfoLength(key)) >= 192)
996 datum=GetStringInfoDatum(aes_info->key);
997 (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
998 (void) CopyMagickMemory(datum,GetStringInfoDatum(key),MagickMin(
999 GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
1000 for (i=0; i < n; i++)
1001 aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) |
1002 (datum[4*i+2] << 16) | (datum[4*i+3] << 24);
1004 bytes=(AESBlocksize/4)*(aes_info->rounds+1);
1005 for (i=n; i < bytes; i++)
1007 alpha=aes_info->encipher_key[i-1];
1010 alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
1011 beta=XTime((unsigned char) (beta & 0xff));
1014 if ((n > 6) && ((i % n) == 4))
1015 alpha=ByteSubTransform(alpha,SBox);
1016 aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
1019 Generate deciper key (in reverse order).
1021 for (i=0; i < 4; i++)
1023 aes_info->decipher_key[i]=aes_info->encipher_key[i];
1024 aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
1026 for (i=4; i < (bytes-4); i+=4)
1027 InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
1031 datum=GetStringInfoDatum(aes_info->key);
1032 (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
1039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1043 % P a s s k e y D e c i p h e r I m a g e %
1047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049 % PasskeyDecipherImage() converts cipher pixels to plain pixels.
1051 % The format of the PasskeyDecipherImage method is:
1053 % MagickBooleanType PasskeyDecipherImage(Image *image,
1054 % const StringInfo *passkey,ExceptionInfo *exception)
1055 % MagickBooleanType DecipherImage(Image *image,const char *passphrase,
1056 % ExceptionInfo *exception)
1058 % A description of each parameter follows:
1060 % o image: the image.
1062 % o passphrase: decipher cipher pixels with this passphrase.
1064 % o passkey: decrypt cipher pixels with this passkey.
1066 % o exception: return any errors or warnings in this structure.
1070 MagickExport MagickBooleanType DecipherImage(Image *image,
1071 const char *passphrase,ExceptionInfo *exception)
1073 assert(image != (Image *) NULL);
1074 assert(image->signature == MagickSignature);
1075 if (image->debug != MagickFalse)
1076 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1077 assert(exception != (ExceptionInfo *) NULL);
1078 assert(exception->signature == MagickSignature);
1080 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1083 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
1084 const StringInfo *passkey,ExceptionInfo *exception)
1086 assert(image != (Image *) NULL);
1087 assert(image->signature == MagickSignature);
1088 if (image->debug != MagickFalse)
1089 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1090 assert(exception != (ExceptionInfo *) NULL);
1091 assert(exception->signature == MagickSignature);
1093 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1101 % P a s s k e y E n c i p h e r I m a g e %
1105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1107 % PasskeyEncipherImage() converts pixels to cipher-pixels.
1109 % The format of the PasskeyEncipherImage method is:
1111 % MagickBooleanType PasskeyEncipherImage(Image *image,
1112 % const StringInfo *passkey,ExceptionInfo *exception)
1113 % MagickBooleanType EncipherImage(Image *image,const char *passphrase,
1114 % ExceptionInfo *exception)
1116 % A description of each parameter follows:
1118 % o passphrase: decipher cipher pixels with this passphrase.
1120 % o passkey: decrypt cipher pixels with this passkey.
1122 % o exception: return any errors or warnings in this structure.
1126 MagickExport MagickBooleanType EncipherImage(Image *image,
1127 const char *passphrase,ExceptionInfo *exception)
1129 assert(image != (Image *) NULL);
1130 assert(image->signature == MagickSignature);
1131 if (image->debug != MagickFalse)
1132 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1133 assert(exception != (ExceptionInfo *) NULL);
1134 assert(exception->signature == MagickSignature);
1136 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1139 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
1140 const StringInfo *passkey,ExceptionInfo *exception)
1142 assert(image != (Image *) NULL);
1143 assert(image->signature == MagickSignature);
1144 if (image->debug != MagickFalse)
1145 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1146 assert(exception != (ExceptionInfo *) NULL);
1147 assert(exception->signature == MagickSignature);
1149 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);