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,
165 *DestroyAESInfo(AESInfo *);
168 EncipherAESBlock(AESInfo *,
const unsigned char *,
unsigned char *),
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));
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;
233 static AESInfo *DestroyAESInfo(AESInfo *aes_info)
235 assert(aes_info != (AESInfo *) NULL);
236 assert(aes_info->signature == MagickCoreSignature);
237 if (IsEventLogging() != MagickFalse)
238 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
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);
246 aes_info->key=DestroyStringInfo(aes_info->key);
247 aes_info->signature=(~MagickCoreSignature);
248 aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
281 static inline void AddRoundKey(
const unsigned int *ciphertext,
282 const unsigned int *key,
unsigned int *plaintext)
290 for (i=0; i < 4; i++)
291 plaintext[i]=key[i] ^ ciphertext[i];
294 static inline unsigned int ByteMultiply(
const unsigned char alpha,
295 const unsigned char beta)
300 if ((alpha == 0) || (beta == 0))
302 return((
unsigned int) InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
305 static inline unsigned int ByteSubTransform(
unsigned int x,
306 unsigned char *s_box)
314 key=((
unsigned int) s_box[x & 0xff]) |
315 ((
unsigned int) s_box[(x >> 8) & 0xff] << 8) |
316 ((
unsigned int) s_box[(x >> 16) & 0xff] << 16) |
317 ((
unsigned int) s_box[(x >> 24) & 0xff] << 24);
321 static void FinalizeRoundKey(
const unsigned int *ciphertext,
322 const unsigned int *key,
unsigned char *plaintext)
338 for (i=0; i < 4; i++)
340 value=ciphertext[i] ^ key[i];
341 for (j=0; j < 4; j++)
342 *p++=(
unsigned char) ((value >> (8*j)) & 0xff);
350 static void InitializeRoundKey(
const unsigned char *ciphertext,
351 const unsigned int *key,
unsigned int *plaintext)
364 for (i=0; i < 4; i++)
367 for (j=0; j < 4; j++)
368 value|=((
unsigned int) *p++ << (8*j));
369 plaintext[i]=key[i] ^ value;
377 static inline unsigned int RotateLeft(
const unsigned int x)
379 return(((x << 8) | ((x >> 24) & 0xff)));
382 static void EncipherAESBlock(AESInfo *aes_info,
const unsigned char *plaintext,
383 unsigned char *ciphertext)
401 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
402 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
403 0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
404 0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
405 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
406 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
407 0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
408 0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
409 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
410 0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
411 0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
412 0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
413 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
414 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
415 0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
416 0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
417 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
418 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
419 0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
420 0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
421 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
422 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
423 0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
424 0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
425 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
426 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
427 0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
428 0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
429 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
430 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
431 0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
432 0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
433 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
434 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
435 0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
436 0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
437 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
438 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
439 0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
440 0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
441 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
442 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
443 0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
444 0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
445 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
446 0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
447 0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
448 0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
449 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
450 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
451 0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
463 (void) memset(text,0,
sizeof(text));
464 InitializeRoundKey(plaintext,aes_info->encipher_key,text);
465 for (i=1; i < aes_info->rounds; i++)
470 for (j=0; j < 4; j++)
471 key[j]=D[text[j] & 0xff] ^
472 RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
473 RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
474 RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
475 AddRoundKey(key,aes_info->encipher_key+4*i,text);
477 for (i=0; i < 4; i++)
479 alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
480 ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
481 key[i]=ByteSubTransform(alpha,SBox);
483 FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
488 (void) ResetMagickMemory(key,0,
sizeof(key));
489 (void) ResetMagickMemory(text,0,
sizeof(text));
524 static inline void IncrementCipherNonce(
const size_t length,
525 unsigned char *nonce)
530 for (i=(ssize_t) (length-1); i >= 0; i--)
536 ThrowFatalException(ResourceLimitFatalError,
"Sequence wrap error `%s'");
539 MagickExport MagickBooleanType DecipherImage(
Image *image,
548 if (passphrase == (
const char *) NULL)
550 passkey=StringToStringInfo(passphrase);
553 status=PasskeyDecipherImage(image,passkey,exception);
554 passkey=DestroyStringInfo(passkey);
558 MagickExport MagickBooleanType PasskeyDecipherImage(
Image *image,
561 #define DecipherImageTag "Decipher/Image "
601 input_block[AESBlocksize],
602 output_block[AESBlocksize],
608 assert(image != (
Image *) NULL);
609 assert(image->signature == MagickCoreSignature);
611 assert(exception->signature == MagickCoreSignature);
612 if (IsEventLogging() != MagickFalse)
613 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
616 aes_info=AcquireAESInfo();
617 key=CloneStringInfo(passkey);
620 aes_info=DestroyAESInfo(aes_info);
621 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
624 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
627 key=DestroyStringInfo(key);
628 aes_info=DestroyAESInfo(aes_info);
629 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
632 SetAESKey(aes_info,key);
633 key=DestroyStringInfo(key);
634 signature_info=AcquireSignatureInfo();
635 UpdateSignature(signature_info,nonce);
636 extent=(MagickSizeType) image->columns*image->rows;
637 SetStringInfoLength(nonce,
sizeof(extent));
638 SetStringInfoDatum(nonce,(
const unsigned char *) &extent);
639 UpdateSignature(signature_info,nonce);
640 nonce=DestroyStringInfo(nonce);
641 FinalizeSignature(signature_info);
642 (void) memset(input_block,0,
sizeof(input_block));
643 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
644 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
645 GetSignatureDigestsize(signature_info))*
sizeof(*input_block));
646 signature_info=DestroySignatureInfo(signature_info);
650 quantum_info=AcquireQuantumInfo((
const ImageInfo *) NULL,image);
653 aes_info=DestroyAESInfo(aes_info);
654 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
657 quantum_type=GetQuantumType(image,exception);
658 pixels=(
unsigned char *) GetQuantumPixels(quantum_info);
659 image_view=AcquireAuthenticCacheView(image,exception);
660 for (y=0; y < (ssize_t) image->rows; y++)
669 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
670 if (q == (Quantum *) NULL)
672 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
675 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
677 (void) memcpy(output_block,input_block,AESBlocksize*
678 sizeof(*output_block));
679 IncrementCipherNonce(AESBlocksize,input_block);
680 EncipherAESBlock(aes_info,output_block,output_block);
681 for (i=0; i < AESBlocksize; i++)
682 p[i]^=output_block[i];
685 (void) memcpy(output_block,input_block,AESBlocksize*
686 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,exception) == 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 signature=StringInfoToHexString(GetSignatureDigest(signature_info));
858 (void) SetImageProperty(image,
"cipher:type",
"AES",exception);
859 (void) SetImageProperty(image,
"cipher:mode",
"CTR",exception);
860 (void) SetImageProperty(image,
"cipher:nonce",signature,exception);
861 signature=DestroyString(signature);
862 (void) memset(input_block,0,
sizeof(input_block));
863 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
864 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
865 GetSignatureDigestsize(signature_info))*
sizeof(*input_block));
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=(
unsigned char *) 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);
890 if (q == (Quantum *) NULL)
892 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
895 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
897 (void) memcpy(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) memcpy(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);