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-2018 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 % https://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/image.h"
47 #include "MagickCore/image-private.h"
48 #include "MagickCore/linked-list.h"
49 #include "MagickCore/list.h"
50 #include "MagickCore/memory_.h"
51 #include "MagickCore/memory-private.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"
63 #if defined(MAGICKCORE_CIPHER_SUPPORT)
67 #define AESBlocksize 16
72 typedef struct _AESInfo
96 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248,
97 19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10,
98 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190,
99 217, 112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204,
100 79, 209, 104, 184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59,
101 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208,
102 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196,
103 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
104 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32,
105 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86,
106 250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237,
107 44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126,
108 130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35,
109 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99,
110 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, 69, 207,
111 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
112 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242,
113 13, 23, 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180,
118 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238,
119 223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200,
120 248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228,
121 166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36,
122 18, 240, 130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208,
123 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253, 48,
124 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110,
125 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
126 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115,
127 167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213,
128 231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245, 89, 203,
129 95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236,
130 216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96,
131 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144,
132 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, 83, 57,
133 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
134 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153,
135 227, 165, 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128,
140 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215,
141 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175,
142 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
143 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154,
144 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
145 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237,
146 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239,
147 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
148 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255,
149 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
150 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238,
151 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92,
152 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213,
153 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46,
154 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
155 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
156 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85,
157 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15,
162 Forward declarations.
165 *DestroyAESInfo(AESInfo *);
168 EncipherAESBlock(AESInfo *,const unsigned char *,unsigned char *),
169 SetAESKey(AESInfo *,const StringInfo *);
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
176 % A c q u i r e A E S I n f o %
180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 % AcquireAESInfo() allocate the AESInfo structure.
184 % The format of the AcquireAESInfo method is:
186 % AESInfo *AcquireAESInfo(void)
189 static AESInfo *AcquireAESInfo(void)
194 aes_info=(AESInfo *) AcquireCriticalMemory(sizeof(*aes_info));
195 (void) memset(aes_info,0,sizeof(*aes_info));
196 aes_info->blocksize=AESBlocksize;
197 aes_info->key=AcquireStringInfo(32);
198 aes_info->encipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
199 *aes_info->encipher_key));
200 aes_info->decipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
201 *aes_info->decipher_key));
202 if ((aes_info->key == (StringInfo *) NULL) ||
203 (aes_info->encipher_key == (unsigned int *) NULL) ||
204 (aes_info->decipher_key == (unsigned int *) NULL))
205 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
206 aes_info->timestamp=(ssize_t) time(0);
207 aes_info->signature=MagickCoreSignature;
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216 % D e s t r o y A E S I n f o %
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 % DestroyAESInfo() zeros memory associated with the AESInfo structure.
224 % The format of the DestroyAESInfo method is:
226 % AESInfo *DestroyAESInfo(AESInfo *aes_info)
228 % A description of each parameter follows:
230 % o aes_info: the cipher context.
233 static AESInfo *DestroyAESInfo(AESInfo *aes_info)
235 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
236 assert(aes_info != (AESInfo *) NULL);
237 assert(aes_info->signature == MagickCoreSignature);
238 if (aes_info->decipher_key != (unsigned int *) NULL)
239 aes_info->decipher_key=(unsigned int *) RelinquishMagickMemory(
240 aes_info->decipher_key);
241 if (aes_info->encipher_key != (unsigned int *) NULL)
242 aes_info->encipher_key=(unsigned int *) RelinquishMagickMemory(
243 aes_info->encipher_key);
244 if (aes_info->key != (StringInfo *) NULL)
245 aes_info->key=DestroyStringInfo(aes_info->key);
246 aes_info->signature=(~MagickCoreSignature);
247 aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
256 % E n c i p h e r A E S B l o c k %
260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
262 % EncipherAESBlock() enciphers a single block of plaintext to produce a block
265 % The format of the EncipherAESBlock method is:
267 % void EncipherAES(AESInfo *aes_info,const unsigned char *plaintext,
268 % unsigned char *ciphertext)
270 % A description of each parameter follows:
272 % o aes_info: the cipher context.
274 % o plaintext: the plain text.
276 % o ciphertext: the cipher text.
280 static inline void AddRoundKey(const unsigned int *ciphertext,
281 const unsigned int *key,unsigned int *plaintext)
287 Xor corresponding text input and round key input bytes.
289 for (i=0; i < 4; i++)
290 plaintext[i]=key[i] ^ ciphertext[i];
293 static inline unsigned char ByteMultiply(const unsigned char alpha,
294 const unsigned char beta)
297 Byte multiply two elements of GF(2^m) (mix columns and inverse mix columns).
299 if ((alpha == 0) || (beta == 0))
301 return(InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
304 static inline unsigned int ByteSubTransform(unsigned int x,
305 unsigned char *s_box)
311 Non-linear layer resists differential and linear cryptoanalysis attacks.
313 key=(s_box[x & 0xff]) | (s_box[(x >> 8) & 0xff] << 8) |
314 (s_box[(x >> 16) & 0xff] << 16) | (s_box[(x >> 24) & 0xff] << 24);
318 static void FinalizeRoundKey(const unsigned int *ciphertext,
319 const unsigned int *key,unsigned char *plaintext)
321 register unsigned char
324 register unsigned int
332 The round key is XORed with the result of the mix-column transformation.
335 for (i=0; i < 4; i++)
337 value=ciphertext[i] ^ key[i];
338 for (j=0; j < 4; j++)
339 *p++=(unsigned char) ((value >> (8*j)) & 0xff);
347 static void InitializeRoundKey(const unsigned char *ciphertext,
348 const unsigned int *key,unsigned int *plaintext)
350 register const unsigned char
353 register unsigned int
361 for (i=0; i < 4; i++)
364 for (j=0; j < 4; j++)
365 value|=(*p++ << (8*j));
366 plaintext[i]=key[i] ^ value;
374 static inline unsigned int RotateLeft(const unsigned int x)
376 return(((x << 8) | ((x >> 24) & 0xff)));
379 static void EncipherAESBlock(AESInfo *aes_info,const unsigned char *plaintext,
380 unsigned char *ciphertext)
398 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
399 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
400 0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
401 0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
402 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
403 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
404 0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
405 0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
406 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
407 0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
408 0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
409 0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
410 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
411 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
412 0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
413 0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
414 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
415 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
416 0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
417 0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
418 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
419 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
420 0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
421 0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
422 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
423 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
424 0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
425 0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
426 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
427 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
428 0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
429 0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
430 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
431 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
432 0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
433 0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
434 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
435 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
436 0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
437 0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
438 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
439 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
440 0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
441 0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
442 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
443 0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
444 0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
445 0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
446 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
447 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
448 0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
460 (void) memset(text,0,sizeof(text));
461 InitializeRoundKey(plaintext,aes_info->encipher_key,text);
462 for (i=1; i < aes_info->rounds; i++)
465 Linear mixing step: cause diffusion of the bits over multiple rounds.
467 for (j=0; j < 4; j++)
468 key[j]=D[text[j] & 0xff] ^
469 RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
470 RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
471 RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
472 AddRoundKey(key,aes_info->encipher_key+4*i,text);
474 for (i=0; i < 4; i++)
476 alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
477 ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
478 key[i]=ByteSubTransform(alpha,SBox);
480 FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
485 (void) memset(key,0,sizeof(key));
486 (void) memset(text,0,sizeof(text));
490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
494 % P a s s k e y D e c i p h e r I m a g e %
498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
500 % PasskeyDecipherImage() converts cipher pixels to plain pixels.
502 % The format of the PasskeyDecipherImage method is:
504 % MagickBooleanType PasskeyDecipherImage(Image *image,
505 % const StringInfo *passkey,ExceptionInfo *exception)
506 % MagickBooleanType DecipherImage(Image *image,const char *passphrase,
507 % ExceptionInfo *exception)
509 % A description of each parameter follows:
511 % o image: the image.
513 % o passphrase: decipher cipher pixels with this passphrase.
515 % o passkey: decrypt cipher pixels with this passkey.
517 % o exception: return any errors or warnings in this structure.
521 static inline void IncrementCipherNonce(const size_t length,
522 unsigned char *nonce)
527 for (i=(ssize_t) (length-1); i >= 0; i--)
533 ThrowFatalException(ResourceLimitFatalError,"Sequence wrap error `%s'");
536 MagickExport MagickBooleanType DecipherImage(Image *image,
537 const char *passphrase,ExceptionInfo *exception)
545 if (passphrase == (const char *) NULL)
547 passkey=StringToStringInfo(passphrase);
548 if (passkey == (StringInfo *) NULL)
550 status=PasskeyDecipherImage(image,passkey,exception);
551 passkey=DestroyStringInfo(passkey);
555 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
556 const StringInfo *passkey,ExceptionInfo *exception)
558 #define DecipherImageTag "Decipher/Image "
584 register unsigned char
598 input_block[AESBlocksize],
599 output_block[AESBlocksize],
603 Generate decipher key and nonce.
605 assert(image != (Image *) NULL);
606 assert(image->signature == MagickCoreSignature);
607 if (image->debug != MagickFalse)
608 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
609 assert(exception != (ExceptionInfo *) NULL);
610 assert(exception->signature == MagickCoreSignature);
611 if (passkey == (const StringInfo *) NULL)
613 aes_info=AcquireAESInfo();
614 key=CloneStringInfo(passkey);
615 if (key == (StringInfo *) NULL)
617 aes_info=DestroyAESInfo(aes_info);
618 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
621 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
622 if (nonce == (StringInfo *) NULL)
624 key=DestroyStringInfo(key);
625 aes_info=DestroyAESInfo(aes_info);
626 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
629 SetAESKey(aes_info,key);
630 key=DestroyStringInfo(key);
631 signature_info=AcquireSignatureInfo();
632 UpdateSignature(signature_info,nonce);
633 extent=(MagickSizeType) image->columns*image->rows;
634 SetStringInfoLength(nonce,sizeof(extent));
635 SetStringInfoDatum(nonce,(const unsigned char *) &extent);
636 UpdateSignature(signature_info,nonce);
637 nonce=DestroyStringInfo(nonce);
638 FinalizeSignature(signature_info);
639 (void) memset(input_block,0,sizeof(input_block));
640 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
641 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
642 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
643 signature_info=DestroySignatureInfo(signature_info);
645 Convert cipher pixels to plain pixels.
647 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
648 if (quantum_info == (QuantumInfo *) NULL)
650 aes_info=DestroyAESInfo(aes_info);
651 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
654 quantum_type=GetQuantumType(image,exception);
655 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
656 image_view=AcquireAuthenticCacheView(image,exception);
657 for (y=0; y < (ssize_t) image->rows; y++)
666 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
667 if (q == (Quantum *) NULL)
669 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
672 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
674 (void) memcpy(output_block,input_block,AESBlocksize*
675 sizeof(*output_block));
676 IncrementCipherNonce(AESBlocksize,input_block);
677 EncipherAESBlock(aes_info,output_block,output_block);
678 for (i=0; i < AESBlocksize; i++)
679 p[i]^=output_block[i];
682 (void) memcpy(output_block,input_block,AESBlocksize*
683 sizeof(*output_block));
684 EncipherAESBlock(aes_info,output_block,output_block);
685 for (i=0; x < (ssize_t) length; x++)
687 p[i]^=output_block[i];
690 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
692 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
694 proceed=SetImageProgress(image,DecipherImageTag,(MagickOffsetType) y,
696 if (proceed == MagickFalse)
699 image_view=DestroyCacheView(image_view);
700 (void) DeleteImageProperty(image,"cipher:type");
701 (void) DeleteImageProperty(image,"cipher:mode");
702 (void) DeleteImageProperty(image,"cipher:nonce");
703 image->taint=MagickFalse;
707 quantum_info=DestroyQuantumInfo(quantum_info);
708 aes_info=DestroyAESInfo(aes_info);
709 (void) memset(input_block,0,sizeof(input_block));
710 (void) memset(output_block,0,sizeof(output_block));
711 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
719 % P a s s k e y E n c i p h e r I m a g e %
723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
725 % PasskeyEncipherImage() converts pixels to cipher-pixels.
727 % The format of the PasskeyEncipherImage method is:
729 % MagickBooleanType PasskeyEncipherImage(Image *image,
730 % const StringInfo *passkey,ExceptionInfo *exception)
731 % MagickBooleanType EncipherImage(Image *image,const char *passphrase,
732 % ExceptionInfo *exception)
734 % A description of each parameter follows:
736 % o image: the image.
738 % o passphrase: encipher pixels with this passphrase.
740 % o passkey: decrypt cipher pixels with this passkey.
742 % o exception: return any errors or warnings in this structure.
746 MagickExport MagickBooleanType EncipherImage(Image *image,
747 const char *passphrase,ExceptionInfo *exception)
755 if (passphrase == (const char *) NULL)
757 passkey=StringToStringInfo(passphrase);
758 if (passkey == (StringInfo *) NULL)
760 status=PasskeyEncipherImage(image,passkey,exception);
761 passkey=DestroyStringInfo(passkey);
765 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
766 const StringInfo *passkey,ExceptionInfo *exception)
768 #define EncipherImageTag "Encipher/Image "
794 register unsigned char
811 input_block[AESBlocksize],
812 output_block[AESBlocksize],
816 Generate encipher key and nonce.
818 assert(image != (Image *) NULL);
819 assert(image->signature == MagickCoreSignature);
820 if (image->debug != MagickFalse)
821 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
822 assert(exception != (ExceptionInfo *) NULL);
823 assert(exception->signature == MagickCoreSignature);
824 if (passkey == (const StringInfo *) NULL)
826 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
828 aes_info=AcquireAESInfo();
829 key=CloneStringInfo(passkey);
830 if (key == (StringInfo *) NULL)
832 aes_info=DestroyAESInfo(aes_info);
833 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
836 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
837 if (nonce == (StringInfo *) NULL)
839 key=DestroyStringInfo(key);
840 aes_info=DestroyAESInfo(aes_info);
841 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
844 SetAESKey(aes_info,key);
845 key=DestroyStringInfo(key);
846 signature_info=AcquireSignatureInfo();
847 UpdateSignature(signature_info,nonce);
848 extent=(MagickSizeType) image->columns*image->rows;
849 SetStringInfoLength(nonce,sizeof(extent));
850 SetStringInfoDatum(nonce,(const unsigned char *) &extent);
851 UpdateSignature(signature_info,nonce);
852 nonce=DestroyStringInfo(nonce);
853 FinalizeSignature(signature_info);
854 signature=StringInfoToHexString(GetSignatureDigest(signature_info));
855 (void) SetImageProperty(image,"cipher:type","AES",exception);
856 (void) SetImageProperty(image,"cipher:mode","CTR",exception);
857 (void) SetImageProperty(image,"cipher:nonce",signature,exception);
858 signature=DestroyString(signature);
859 (void) memset(input_block,0,sizeof(input_block));
860 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
861 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
862 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
863 signature_info=DestroySignatureInfo(signature_info);
865 Convert plain pixels to cipher pixels.
867 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
868 if (quantum_info == (QuantumInfo *) NULL)
870 aes_info=DestroyAESInfo(aes_info);
871 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
874 quantum_type=GetQuantumType(image,exception);
875 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
876 image_view=AcquireAuthenticCacheView(image,exception);
877 for (y=0; y < (ssize_t) image->rows; y++)
886 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
887 if (q == (Quantum *) NULL)
889 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
892 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
894 (void) memcpy(output_block,input_block,AESBlocksize*
895 sizeof(*output_block));
896 IncrementCipherNonce(AESBlocksize,input_block);
897 EncipherAESBlock(aes_info,output_block,output_block);
898 for (i=0; i < AESBlocksize; i++)
899 p[i]^=output_block[i];
902 (void) memcpy(output_block,input_block,AESBlocksize*
903 sizeof(*output_block));
904 EncipherAESBlock(aes_info,output_block,output_block);
905 for (i=0; x < (ssize_t) length; x++)
907 p[i]^=output_block[i];
910 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
912 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
914 proceed=SetImageProgress(image,EncipherImageTag,(MagickOffsetType) y,
916 if (proceed == MagickFalse)
919 image_view=DestroyCacheView(image_view);
920 image->taint=MagickFalse;
924 quantum_info=DestroyQuantumInfo(quantum_info);
925 aes_info=DestroyAESInfo(aes_info);
926 (void) memset(input_block,0,sizeof(input_block));
927 (void) memset(output_block,0,sizeof(output_block));
928 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
936 % S e t A E S K e y %
940 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942 % SetAESKey() sets the key for the AES cipher. The key length is specified
943 % in bits. Valid values are 128, 192, or 256 requiring a key buffer length
944 % in bytes of 16, 24, and 32 respectively.
946 % The format of the SetAESKey method is:
948 % SetAESKey(AESInfo *aes_info,const StringInfo *key)
950 % A description of each parameter follows:
952 % o aes_info: the cipher context.
958 static inline void InverseAddRoundKey(const unsigned int *alpha,
961 register unsigned int
965 for (i=0; i < 4; i++)
968 for (j=0; j < 4; j++)
969 beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
970 ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
971 ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
972 ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
976 static inline unsigned int XTime(unsigned char alpha)
981 beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
987 static inline unsigned int RotateRight(const unsigned int x)
989 return((x >> 8) | ((x & 0xff) << 24));
992 static void SetAESKey(AESInfo *aes_info,const StringInfo *key)
1009 Determine the number of rounds based on the number of bits in key.
1011 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1012 assert(aes_info != (AESInfo *) NULL);
1013 assert(aes_info->signature == MagickCoreSignature);
1014 assert(key != (StringInfo *) NULL);
1016 aes_info->rounds=10;
1017 if ((8*GetStringInfoLength(key)) >= 256)
1020 aes_info->rounds=14;
1023 if ((8*GetStringInfoLength(key)) >= 192)
1026 aes_info->rounds=12;
1031 datum=GetStringInfoDatum(aes_info->key);
1032 (void) memset(datum,0,GetStringInfoLength(aes_info->key));
1033 (void) memcpy(datum,GetStringInfoDatum(key),MagickMin(
1034 GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
1035 for (i=0; i < n; i++)
1036 aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) |
1037 (datum[4*i+2] << 16) | (datum[4*i+3] << 24);
1039 bytes=(AESBlocksize/4)*(aes_info->rounds+1);
1040 for (i=n; i < bytes; i++)
1042 alpha=aes_info->encipher_key[i-1];
1045 alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
1046 beta=XTime((unsigned char) (beta & 0xff));
1049 if ((n > 6) && ((i % n) == 4))
1050 alpha=ByteSubTransform(alpha,SBox);
1051 aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
1054 Generate deciper key (in reverse order).
1056 for (i=0; i < 4; i++)
1058 aes_info->decipher_key[i]=aes_info->encipher_key[i];
1059 aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
1061 for (i=4; i < (bytes-4); i+=4)
1062 InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
1066 datum=GetStringInfoDatum(aes_info->key);
1067 (void) memset(datum,0,GetStringInfoLength(aes_info->key));
1074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1078 % P a s s k e y D e c i p h e r I m a g e %
1082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1084 % PasskeyDecipherImage() converts cipher pixels to plain pixels.
1086 % The format of the PasskeyDecipherImage method is:
1088 % MagickBooleanType PasskeyDecipherImage(Image *image,
1089 % const StringInfo *passkey,ExceptionInfo *exception)
1090 % MagickBooleanType DecipherImage(Image *image,const char *passphrase,
1091 % ExceptionInfo *exception)
1093 % A description of each parameter follows:
1095 % o image: the image.
1097 % o passphrase: decipher cipher pixels with this passphrase.
1099 % o passkey: decrypt cipher pixels with this passkey.
1101 % o exception: return any errors or warnings in this structure.
1105 MagickExport MagickBooleanType DecipherImage(Image *image,
1106 const char *passphrase,ExceptionInfo *exception)
1108 assert(image != (Image *) NULL);
1109 assert(image->signature == MagickCoreSignature);
1110 if (image->debug != MagickFalse)
1111 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1112 assert(exception != (ExceptionInfo *) NULL);
1113 assert(exception->signature == MagickCoreSignature);
1115 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1118 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
1119 const StringInfo *passkey,ExceptionInfo *exception)
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);
1128 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1136 % P a s s k e y E n c i p h e r I m a g e %
1140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1142 % PasskeyEncipherImage() converts pixels to cipher-pixels.
1144 % The format of the PasskeyEncipherImage method is:
1146 % MagickBooleanType PasskeyEncipherImage(Image *image,
1147 % const StringInfo *passkey,ExceptionInfo *exception)
1148 % MagickBooleanType EncipherImage(Image *image,const char *passphrase,
1149 % ExceptionInfo *exception)
1151 % A description of each parameter follows:
1153 % o passphrase: decipher cipher pixels with this passphrase.
1155 % o passkey: decrypt cipher pixels with this passkey.
1157 % o exception: return any errors or warnings in this structure.
1161 MagickExport MagickBooleanType EncipherImage(Image *image,
1162 const char *passphrase,ExceptionInfo *exception)
1164 assert(image != (Image *) NULL);
1165 assert(image->signature == MagickCoreSignature);
1166 if (image->debug != MagickFalse)
1167 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1168 assert(exception != (ExceptionInfo *) NULL);
1169 assert(exception->signature == MagickCoreSignature);
1171 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1174 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
1175 const StringInfo *passkey,ExceptionInfo *exception)
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);
1184 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);