41 #include "magick/studio.h"
42 #include "magick/cache.h"
43 #include "magick/cipher.h"
44 #include "magick/exception.h"
45 #include "magick/exception-private.h"
46 #include "magick/hashmap.h"
47 #include "magick/image.h"
48 #include "magick/image-private.h"
49 #include "magick/list.h"
50 #include "magick/memory_.h"
51 #include "magick/monitor.h"
52 #include "magick/monitor-private.h"
53 #include "magick/property.h"
54 #include "magick/quantum-private.h"
55 #include "magick/registry.h"
56 #include "magick/semaphore.h"
57 #include "magick/signature-private.h"
58 #include "magick/splay-tree.h"
59 #include "magick/statistic.h"
60 #include "magick/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,
164 *DestroyAESInfo(AESInfo *);
167 EncipherAESBlock(AESInfo *,
const unsigned char *,
unsigned char *),
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) memset(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));
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=MagickCoreSignature;
234 static AESInfo *DestroyAESInfo(AESInfo *aes_info)
236 assert(aes_info != (AESInfo *) NULL);
237 assert(aes_info->signature == MagickCoreSignature);
238 if (IsEventLogging() != MagickFalse)
239 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
240 if (aes_info->decipher_key != (
unsigned int *) NULL)
241 aes_info->decipher_key=(
unsigned int *) RelinquishMagickMemory(
242 aes_info->decipher_key);
243 if (aes_info->encipher_key != (
unsigned int *) NULL)
244 aes_info->encipher_key=(
unsigned int *) RelinquishMagickMemory(
245 aes_info->encipher_key);
247 aes_info->key=DestroyStringInfo(aes_info->key);
248 aes_info->signature=(~MagickCoreSignature);
249 aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
282 static inline void AddRoundKey(
const unsigned int *ciphertext,
283 const unsigned int *key,
unsigned int *plaintext)
291 for (i=0; i < 4; i++)
292 plaintext[i]=key[i] ^ ciphertext[i];
295 static inline unsigned int ByteMultiply(
const unsigned char alpha,
296 const unsigned char beta)
301 if ((alpha == 0) || (beta == 0))
303 return((
unsigned int) InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
306 static inline unsigned int ByteSubTransform(
unsigned int x,
307 unsigned char *s_box)
315 key=((
unsigned int) s_box[x & 0xff]) |
316 ((
unsigned int) s_box[(x >> 8) & 0xff] << 8) |
317 ((
unsigned int) s_box[(x >> 16) & 0xff] << 16) |
318 ((
unsigned int) s_box[(x >> 24) & 0xff] << 24);
322 static void FinalizeRoundKey(
const unsigned int *ciphertext,
323 const unsigned int *key,
unsigned char *plaintext)
339 for (i=0; i < 4; i++)
341 value=ciphertext[i] ^ key[i];
342 for (j=0; j < 4; j++)
343 *p++=(
unsigned char) ((value >> (8*j)) & 0xff);
351 static void InitializeRoundKey(
const unsigned char *ciphertext,
352 const unsigned int *key,
unsigned int *plaintext)
365 for (i=0; i < 4; i++)
368 for (j=0; j < 4; j++)
369 value|=((
unsigned int) *p++ << (8*j));
370 plaintext[i]=key[i] ^ value;
378 static inline unsigned int RotateLeft(
const unsigned int x)
380 return(((x << 8) | ((x >> 24) & 0xff)));
383 static void EncipherAESBlock(AESInfo *aes_info,
const unsigned char *plaintext,
384 unsigned char *ciphertext)
402 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
403 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
404 0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
405 0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
406 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
407 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
408 0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
409 0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
410 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
411 0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
412 0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
413 0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
414 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
415 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
416 0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
417 0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
418 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
419 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
420 0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
421 0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
422 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
423 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
424 0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
425 0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
426 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
427 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
428 0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
429 0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
430 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
431 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
432 0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
433 0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
434 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
435 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
436 0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
437 0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
438 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
439 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
440 0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
441 0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
442 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
443 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
444 0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
445 0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
446 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
447 0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
448 0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
449 0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
450 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
451 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
452 0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
464 (void) memset(text,0,
sizeof(text));
465 InitializeRoundKey(plaintext,aes_info->encipher_key,text);
466 for (i=1; i < aes_info->rounds; i++)
471 for (j=0; j < 4; j++)
472 key[j]=D[text[j] & 0xff] ^
473 RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
474 RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
475 RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
476 AddRoundKey(key,aes_info->encipher_key+4*i,text);
478 for (i=0; i < 4; i++)
480 alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
481 ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
482 key[i]=ByteSubTransform(alpha,SBox);
484 FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
489 (void) ResetMagickMemory(key,0,
sizeof(key));
490 (void) ResetMagickMemory(text,0,
sizeof(text));
525 static inline void IncrementCipherNonce(
const size_t length,
526 unsigned char *nonce)
531 for (i=(ssize_t) (length-1); i >= 0; i--)
537 ThrowFatalException(ResourceLimitFatalError,
"Sequence wrap error `%s'");
540 MagickExport MagickBooleanType DecipherImage(
Image *image,
549 if (passphrase == (
const char *) NULL)
551 passkey=StringToStringInfo(passphrase);
554 status=PasskeyDecipherImage(image,passkey,exception);
555 passkey=DestroyStringInfo(passkey);
559 MagickExport MagickBooleanType PasskeyDecipherImage(
Image *image,
562 #define DecipherImageTag "Decipher/Image "
602 input_block[AESBlocksize],
603 output_block[AESBlocksize],
609 assert(image != (
Image *) NULL);
610 assert(image->signature == MagickCoreSignature);
612 assert(exception->signature == MagickCoreSignature);
613 if (IsEventLogging() != MagickFalse)
614 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
617 aes_info=AcquireAESInfo();
618 key=CloneStringInfo(passkey);
621 aes_info=DestroyAESInfo(aes_info);
622 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
625 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
628 key=DestroyStringInfo(key);
629 aes_info=DestroyAESInfo(aes_info);
630 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
633 SetAESKey(aes_info,key);
634 key=DestroyStringInfo(key);
635 signature_info=AcquireSignatureInfo();
636 UpdateSignature(signature_info,nonce);
637 extent=(MagickSizeType) image->columns*image->rows;
638 SetStringInfoLength(nonce,
sizeof(extent));
639 SetStringInfoDatum(nonce,(
const unsigned char *) &extent);
640 UpdateSignature(signature_info,nonce);
641 nonce=DestroyStringInfo(nonce);
642 FinalizeSignature(signature_info);
643 (void) memset(input_block,0,
sizeof(input_block));
644 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
645 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
646 GetSignatureDigestsize(signature_info))*
sizeof(*input_block));
647 signature_info=DestroySignatureInfo(signature_info);
651 quantum_info=AcquireQuantumInfo((
const ImageInfo *) NULL,image);
654 aes_info=DestroyAESInfo(aes_info);
655 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
658 quantum_type=GetQuantumType(image,exception);
659 pixels=GetQuantumPixels(quantum_info);
660 image_view=AcquireAuthenticCacheView(image,exception);
661 for (y=0; y < (ssize_t) image->rows; y++)
670 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
673 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
676 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
678 (void) memmove(output_block,input_block,AESBlocksize*
679 sizeof(*output_block));
680 IncrementCipherNonce(AESBlocksize,input_block);
681 EncipherAESBlock(aes_info,output_block,output_block);
682 for (i=0; i < AESBlocksize; i++)
683 p[i]^=output_block[i];
686 (void) memmove(output_block,input_block,AESBlocksize*
sizeof(*output_block));
687 EncipherAESBlock(aes_info,output_block,output_block);
688 for (i=0; x < (ssize_t) length; x++)
690 p[i]^=output_block[i];
693 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
695 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
697 proceed=SetImageProgress(image,DecipherImageTag,(MagickOffsetType) y,
699 if (proceed == MagickFalse)
702 image_view=DestroyCacheView(image_view);
703 (void) DeleteImageProperty(image,
"cipher:type");
704 (void) DeleteImageProperty(image,
"cipher:mode");
705 (void) DeleteImageProperty(image,
"cipher:nonce");
706 image->taint=MagickFalse;
710 quantum_info=DestroyQuantumInfo(quantum_info);
711 aes_info=DestroyAESInfo(aes_info);
712 (void) ResetMagickMemory(input_block,0,
sizeof(input_block));
713 (void) ResetMagickMemory(output_block,0,
sizeof(output_block));
714 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
749 MagickExport MagickBooleanType EncipherImage(
Image *image,
758 if (passphrase == (
const char *) NULL)
760 passkey=StringToStringInfo(passphrase);
763 status=PasskeyEncipherImage(image,passkey,exception);
764 passkey=DestroyStringInfo(passkey);
768 MagickExport MagickBooleanType PasskeyEncipherImage(
Image *image,
771 #define EncipherImageTag "Encipher/Image "
814 input_block[AESBlocksize],
815 output_block[AESBlocksize],
821 assert(image != (
Image *) NULL);
822 assert(image->signature == MagickCoreSignature);
824 assert(exception->signature == MagickCoreSignature);
825 if (IsEventLogging() != MagickFalse)
826 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
829 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
831 aes_info=AcquireAESInfo();
832 key=CloneStringInfo(passkey);
835 aes_info=DestroyAESInfo(aes_info);
836 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
839 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
842 key=DestroyStringInfo(key);
843 aes_info=DestroyAESInfo(aes_info);
844 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
847 SetAESKey(aes_info,key);
848 key=DestroyStringInfo(key);
849 signature_info=AcquireSignatureInfo();
850 UpdateSignature(signature_info,nonce);
851 extent=(MagickSizeType) image->columns*image->rows;
852 SetStringInfoLength(nonce,
sizeof(extent));
853 SetStringInfoDatum(nonce,(
const unsigned char *) &extent);
854 UpdateSignature(signature_info,nonce);
855 nonce=DestroyStringInfo(nonce);
856 FinalizeSignature(signature_info);
857 (void) memset(input_block,0,
sizeof(input_block));
858 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
859 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
860 GetSignatureDigestsize(signature_info))*
sizeof(*input_block));
861 signature=StringInfoToHexString(GetSignatureDigest(signature_info));
862 (void) SetImageProperty(image,
"cipher:type",
"AES");
863 (void) SetImageProperty(image,
"cipher:mode",
"CTR");
864 (void) SetImageProperty(image,
"cipher:nonce",signature);
865 signature=DestroyString(signature);
866 signature_info=DestroySignatureInfo(signature_info);
870 quantum_info=AcquireQuantumInfo((
const ImageInfo *) NULL,image);
873 aes_info=DestroyAESInfo(aes_info);
874 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
877 quantum_type=GetQuantumType(image,exception);
878 pixels=GetQuantumPixels(quantum_info);
879 image_view=AcquireAuthenticCacheView(image,exception);
880 for (y=0; y < (ssize_t) image->rows; y++)
889 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
892 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
895 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
897 (void) memmove(output_block,input_block,AESBlocksize*
898 sizeof(*output_block));
899 IncrementCipherNonce(AESBlocksize,input_block);
900 EncipherAESBlock(aes_info,output_block,output_block);
901 for (i=0; i < AESBlocksize; i++)
902 p[i]^=output_block[i];
905 (void) memmove(output_block,input_block,AESBlocksize*
906 sizeof(*output_block));
907 EncipherAESBlock(aes_info,output_block,output_block);
908 for (i=0; x < (ssize_t) length; x++)
910 p[i]^=output_block[i];
913 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
915 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
917 proceed=SetImageProgress(image,EncipherImageTag,(MagickOffsetType) y,
919 if (proceed == MagickFalse)
922 image_view=DestroyCacheView(image_view);
923 image->taint=MagickFalse;
927 quantum_info=DestroyQuantumInfo(quantum_info);
928 aes_info=DestroyAESInfo(aes_info);
929 (void) ResetMagickMemory(input_block,0,
sizeof(input_block));
930 (void) ResetMagickMemory(output_block,0,
sizeof(output_block));
931 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
961 static inline void InverseAddRoundKey(
const unsigned int *alpha,
968 for (i=0; i < 4; i++)
971 for (j=0; j < 4; j++)
972 beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
973 ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
974 ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
975 ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
979 static inline unsigned int XTime(
unsigned char alpha)
984 beta=(
unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
990 static inline unsigned int RotateRight(
const unsigned int x)
992 return((x >> 8) | ((x & 0xff) << 24));
995 static void SetAESKey(AESInfo *aes_info,
const StringInfo *key)
1014 assert(aes_info != (AESInfo *) NULL);
1015 assert(aes_info->signature == MagickCoreSignature);
1017 if (IsEventLogging() != MagickFalse)
1018 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
1020 aes_info->rounds=10;
1021 if ((8*GetStringInfoLength(key)) >= 256)
1024 aes_info->rounds=14;
1027 if ((8*GetStringInfoLength(key)) >= 192)
1030 aes_info->rounds=12;
1035 datum=GetStringInfoDatum(aes_info->key);
1036 (void) memset(datum,0,GetStringInfoLength(aes_info->key));
1037 (void) memcpy(datum,GetStringInfoDatum(key),MagickMin(
1038 GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
1039 for (i=0; i < n; i++)
1040 aes_info->encipher_key[i]=(
unsigned int) datum[4*i] |
1041 ((
unsigned int) datum[4*i+1] << 8) |
1042 ((
unsigned int) datum[4*i+2] << 16) |
1043 ((
unsigned int) datum[4*i+3] << 24);
1045 bytes=(AESBlocksize/4)*(aes_info->rounds+1);
1046 for (i=n; i < bytes; i++)
1048 alpha=aes_info->encipher_key[i-1];
1051 alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
1052 beta=XTime((
unsigned char) (beta & 0xff));
1055 if ((n > 6) && ((i % n) == 4))
1056 alpha=ByteSubTransform(alpha,SBox);
1057 aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
1062 for (i=0; i < 4; i++)
1064 aes_info->decipher_key[i]=aes_info->encipher_key[i];
1065 aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
1067 for (i=4; i < (bytes-4); i+=4)
1068 InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
1072 datum=GetStringInfoDatum(aes_info->key);
1073 (void) memset(datum,0,GetStringInfoLength(aes_info->key));
1111 MagickExport MagickBooleanType DecipherImage(
Image *image,
1114 assert(image != (
Image *) NULL);
1115 assert(image->signature == MagickCoreSignature);
1117 assert(exception->signature == MagickCoreSignature);
1118 if (IsEventLogging() != MagickFalse)
1119 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1121 ThrowBinaryException(ImageError,
"CipherSupportNotEnabled",image->filename);
1124 MagickExport MagickBooleanType PasskeyDecipherImage(
Image *image,
1127 assert(image != (
Image *) NULL);
1128 assert(image->signature == MagickCoreSignature);
1130 assert(exception->signature == MagickCoreSignature);
1131 if (IsEventLogging() != MagickFalse)
1132 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1134 ThrowBinaryException(ImageError,
"CipherSupportNotEnabled",image->filename);
1167 MagickExport MagickBooleanType EncipherImage(
Image *image,
1170 assert(image != (
Image *) NULL);
1171 assert(image->signature == MagickCoreSignature);
1173 assert(exception->signature == MagickCoreSignature);
1174 if (IsEventLogging() != MagickFalse)
1175 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1177 ThrowBinaryException(ImageError,
"CipherSupportNotEnabled",image->filename);
1180 MagickExport MagickBooleanType PasskeyEncipherImage(
Image *image,
1183 assert(image != (
Image *) NULL);
1184 assert(image->signature == MagickCoreSignature);
1186 assert(exception->signature == MagickCoreSignature);
1187 if (IsEventLogging() != MagickFalse)
1188 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1190 ThrowBinaryException(ImageError,
"CipherSupportNotEnabled",image->filename);