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"
62#include "MagickCore/timer-private.h"
64#if defined(MAGICKCORE_CIPHER_SUPPORT)
68#define AESBlocksize 16
73typedef struct _AESInfo
99 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248,
100 19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10,
101 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190,
102 217, 112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204,
103 79, 209, 104, 184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59,
104 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208,
105 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196,
106 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
107 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32,
108 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86,
109 250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237,
110 44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126,
111 130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35,
112 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99,
113 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, 69, 207,
114 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
115 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242,
116 13, 23, 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180,
121 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238,
122 223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200,
123 248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228,
124 166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36,
125 18, 240, 130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208,
126 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253, 48,
127 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110,
128 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
129 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115,
130 167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213,
131 231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245, 89, 203,
132 95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236,
133 216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96,
134 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144,
135 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, 83, 57,
136 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
137 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153,
138 227, 165, 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128,
143 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215,
144 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175,
145 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
146 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154,
147 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
148 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237,
149 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239,
150 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
151 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255,
152 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
153 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238,
154 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92,
155 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213,
156 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46,
157 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
158 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
159 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85,
160 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15,
168 *DestroyAESInfo(AESInfo *);
171 EncipherAESBlock(AESInfo *,
const unsigned char *,
unsigned char *),
192static AESInfo *AcquireAESInfo(
void)
197 aes_info=(AESInfo *) AcquireCriticalMemory(
sizeof(*aes_info));
198 (void) memset(aes_info,0,
sizeof(*aes_info));
199 aes_info->blocksize=AESBlocksize;
200 aes_info->key=AcquireStringInfo(32);
201 aes_info->encipher_key=(
unsigned int *) AcquireQuantumMemory(60UL,
sizeof(
202 *aes_info->encipher_key));
203 aes_info->decipher_key=(
unsigned int *) AcquireQuantumMemory(60UL,
sizeof(
204 *aes_info->decipher_key));
206 (aes_info->encipher_key == (
unsigned int *) NULL) ||
207 (aes_info->decipher_key == (
unsigned int *) NULL))
208 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
209 aes_info->timestamp=GetMagickTime();
210 aes_info->signature=MagickCoreSignature;
236static AESInfo *DestroyAESInfo(AESInfo *aes_info)
238 assert(aes_info != (AESInfo *) NULL);
239 assert(aes_info->signature == MagickCoreSignature);
240 if (IsEventLogging() != MagickFalse)
241 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
242 if (aes_info->decipher_key != (
unsigned int *) NULL)
243 aes_info->decipher_key=(
unsigned int *) RelinquishMagickMemory(
244 aes_info->decipher_key);
245 if (aes_info->encipher_key != (
unsigned int *) NULL)
246 aes_info->encipher_key=(
unsigned int *) RelinquishMagickMemory(
247 aes_info->encipher_key);
249 aes_info->key=DestroyStringInfo(aes_info->key);
250 aes_info->signature=(~MagickCoreSignature);
251 aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
284static inline void AddRoundKey(
const unsigned int *ciphertext,
285 const unsigned int *key,
unsigned int *plaintext)
293 for (i=0; i < 4; i++)
294 plaintext[i]=key[i] ^ ciphertext[i];
297static inline unsigned int ByteMultiply(
const unsigned char alpha,
298 const unsigned char beta)
303 if ((alpha == 0) || (beta == 0))
305 return((
unsigned int) InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
308static inline unsigned int ByteSubTransform(
unsigned int x,
309 unsigned char *s_box)
317 key=((
unsigned int) s_box[x & 0xff]) |
318 ((
unsigned int) s_box[(x >> 8) & 0xff] << 8) |
319 ((
unsigned int) s_box[(x >> 16) & 0xff] << 16) |
320 ((
unsigned int) s_box[(x >> 24) & 0xff] << 24);
324static void FinalizeRoundKey(
const unsigned int *ciphertext,
325 const unsigned int *key,
unsigned char *plaintext)
341 for (i=0; i < 4; i++)
343 value=ciphertext[i] ^ key[i];
344 for (j=0; j < 4; j++)
345 *p++=(
unsigned char) ((value >> (8*j)) & 0xff);
353static void InitializeRoundKey(
const unsigned char *ciphertext,
354 const unsigned int *key,
unsigned int *plaintext)
367 for (i=0; i < 4; i++)
370 for (j=0; j < 4; j++)
371 value|=((
unsigned int) *p++ << (8*j));
372 plaintext[i]=key[i] ^ value;
380static inline unsigned int RotateLeft(
const unsigned int x)
382 return(((x << 8) | ((x >> 24) & 0xff)));
385static void EncipherAESBlock(AESInfo *aes_info,
const unsigned char *plaintext,
386 unsigned char *ciphertext)
404 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
405 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
406 0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
407 0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
408 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
409 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
410 0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
411 0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
412 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
413 0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
414 0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
415 0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
416 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
417 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
418 0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
419 0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
420 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
421 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
422 0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
423 0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
424 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
425 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
426 0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
427 0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
428 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
429 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
430 0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
431 0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
432 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
433 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
434 0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
435 0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
436 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
437 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
438 0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
439 0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
440 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
441 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
442 0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
443 0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
444 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
445 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
446 0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
447 0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
448 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
449 0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
450 0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
451 0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
452 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
453 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
454 0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
466 (void) memset(text,0,
sizeof(text));
467 InitializeRoundKey(plaintext,aes_info->encipher_key,text);
468 for (i=1; i < aes_info->rounds; i++)
473 for (j=0; j < 4; j++)
474 key[j]=D[text[j] & 0xff] ^
475 RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
476 RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
477 RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
478 AddRoundKey(key,aes_info->encipher_key+4*i,text);
480 for (i=0; i < 4; i++)
482 alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
483 ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
484 key[i]=ByteSubTransform(alpha,SBox);
486 FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
491 (void) ResetMagickMemory(key,0,
sizeof(key));
492 (void) ResetMagickMemory(text,0,
sizeof(text));
527static inline void IncrementCipherNonce(
const size_t length,
528 unsigned char *nonce)
533 for (i=(ssize_t) (length-1); i >= 0; i--)
539 ThrowFatalException(ResourceLimitFatalError,
"Sequence wrap error `%s'");
542MagickExport MagickBooleanType DecipherImage(
Image *image,
551 if (passphrase == (
const char *) NULL)
553 passkey=StringToStringInfo(passphrase);
556 status=PasskeyDecipherImage(image,passkey,exception);
557 passkey=DestroyStringInfo(passkey);
561MagickExport MagickBooleanType PasskeyDecipherImage(
Image *image,
564#define DecipherImageTag "Decipher/Image "
604 input_block[AESBlocksize],
605 output_block[AESBlocksize],
611 assert(image != (
Image *) NULL);
612 assert(image->signature == MagickCoreSignature);
614 assert(exception->signature == MagickCoreSignature);
615 if (IsEventLogging() != MagickFalse)
616 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
619 aes_info=AcquireAESInfo();
620 key=CloneStringInfo(passkey);
623 aes_info=DestroyAESInfo(aes_info);
624 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
627 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
630 key=DestroyStringInfo(key);
631 aes_info=DestroyAESInfo(aes_info);
632 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
635 SetAESKey(aes_info,key);
636 key=DestroyStringInfo(key);
637 signature_info=AcquireSignatureInfo();
638 UpdateSignature(signature_info,nonce);
639 extent=(MagickSizeType) image->columns*image->rows;
640 SetStringInfoLength(nonce,
sizeof(extent));
641 SetStringInfoDatum(nonce,(
const unsigned char *) &extent);
642 UpdateSignature(signature_info,nonce);
643 nonce=DestroyStringInfo(nonce);
644 FinalizeSignature(signature_info);
645 (void) memset(input_block,0,
sizeof(input_block));
646 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
647 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
648 GetSignatureDigestsize(signature_info))*
sizeof(*input_block));
649 signature_info=DestroySignatureInfo(signature_info);
653 quantum_info=AcquireQuantumInfo((
const ImageInfo *) NULL,image);
656 aes_info=DestroyAESInfo(aes_info);
657 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
660 quantum_type=GetQuantumType(image,exception);
661 pixels=(
unsigned char *) GetQuantumPixels(quantum_info);
662 image_view=AcquireAuthenticCacheView(image,exception);
663 for (y=0; y < (ssize_t) image->rows; y++)
672 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
673 if (q == (Quantum *) NULL)
675 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
678 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
680 (void) memcpy(output_block,input_block,AESBlocksize*
681 sizeof(*output_block));
682 IncrementCipherNonce(AESBlocksize,input_block);
683 EncipherAESBlock(aes_info,output_block,output_block);
684 for (i=0; i < AESBlocksize; i++)
685 p[i]^=output_block[i];
686 p+=(ptrdiff_t) AESBlocksize;
688 (void) memcpy(output_block,input_block,AESBlocksize*
689 sizeof(*output_block));
690 EncipherAESBlock(aes_info,output_block,output_block);
691 for (i=0; x < (ssize_t) length; x++)
693 p[i]^=output_block[i];
696 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
698 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
700 proceed=SetImageProgress(image,DecipherImageTag,(MagickOffsetType) y,
702 if (proceed == MagickFalse)
705 image_view=DestroyCacheView(image_view);
706 (void) DeleteImageProperty(image,
"cipher:type");
707 (void) DeleteImageProperty(image,
"cipher:mode");
708 (void) DeleteImageProperty(image,
"cipher:nonce");
709 image->taint=MagickFalse;
713 quantum_info=DestroyQuantumInfo(quantum_info);
714 aes_info=DestroyAESInfo(aes_info);
715 (void) ResetMagickMemory(input_block,0,
sizeof(input_block));
716 (void) ResetMagickMemory(output_block,0,
sizeof(output_block));
717 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
752MagickExport MagickBooleanType EncipherImage(
Image *image,
761 if (passphrase == (
const char *) NULL)
763 passkey=StringToStringInfo(passphrase);
766 status=PasskeyEncipherImage(image,passkey,exception);
767 passkey=DestroyStringInfo(passkey);
771MagickExport MagickBooleanType PasskeyEncipherImage(
Image *image,
774#define EncipherImageTag "Encipher/Image "
817 input_block[AESBlocksize],
818 output_block[AESBlocksize],
824 assert(image != (
Image *) NULL);
825 assert(image->signature == MagickCoreSignature);
827 assert(exception->signature == MagickCoreSignature);
828 if (IsEventLogging() != MagickFalse)
829 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
832 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
834 aes_info=AcquireAESInfo();
835 key=CloneStringInfo(passkey);
838 aes_info=DestroyAESInfo(aes_info);
839 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
842 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
845 key=DestroyStringInfo(key);
846 aes_info=DestroyAESInfo(aes_info);
847 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
850 SetAESKey(aes_info,key);
851 key=DestroyStringInfo(key);
852 signature_info=AcquireSignatureInfo();
853 UpdateSignature(signature_info,nonce);
854 extent=(MagickSizeType) image->columns*image->rows;
855 SetStringInfoLength(nonce,
sizeof(extent));
856 SetStringInfoDatum(nonce,(
const unsigned char *) &extent);
857 UpdateSignature(signature_info,nonce);
858 nonce=DestroyStringInfo(nonce);
859 FinalizeSignature(signature_info);
860 signature=StringInfoToHexString(GetSignatureDigest(signature_info));
861 (void) SetImageProperty(image,
"cipher:type",
"AES",exception);
862 (void) SetImageProperty(image,
"cipher:mode",
"CTR",exception);
863 (void) SetImageProperty(image,
"cipher:nonce",signature,exception);
864 signature=DestroyString(signature);
865 (void) memset(input_block,0,
sizeof(input_block));
866 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
867 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
868 GetSignatureDigestsize(signature_info))*
sizeof(*input_block));
869 signature_info=DestroySignatureInfo(signature_info);
873 quantum_info=AcquireQuantumInfo((
const ImageInfo *) NULL,image);
876 aes_info=DestroyAESInfo(aes_info);
877 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
880 quantum_type=GetQuantumType(image,exception);
881 pixels=(
unsigned char *) GetQuantumPixels(quantum_info);
882 image_view=AcquireAuthenticCacheView(image,exception);
883 for (y=0; y < (ssize_t) image->rows; y++)
892 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
893 if (q == (Quantum *) NULL)
895 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
898 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
900 (void) memcpy(output_block,input_block,AESBlocksize*
901 sizeof(*output_block));
902 IncrementCipherNonce(AESBlocksize,input_block);
903 EncipherAESBlock(aes_info,output_block,output_block);
904 for (i=0; i < AESBlocksize; i++)
905 p[i]^=output_block[i];
906 p+=(ptrdiff_t) AESBlocksize;
908 (void) memcpy(output_block,input_block,AESBlocksize*
909 sizeof(*output_block));
910 EncipherAESBlock(aes_info,output_block,output_block);
911 for (i=0; x < (ssize_t) length; x++)
913 p[i]^=output_block[i];
916 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
918 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
920 proceed=SetImageProgress(image,EncipherImageTag,(MagickOffsetType) y,
922 if (proceed == MagickFalse)
925 image_view=DestroyCacheView(image_view);
926 image->taint=MagickFalse;
930 quantum_info=DestroyQuantumInfo(quantum_info);
931 aes_info=DestroyAESInfo(aes_info);
932 (void) ResetMagickMemory(input_block,0,
sizeof(input_block));
933 (void) ResetMagickMemory(output_block,0,
sizeof(output_block));
934 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
964static inline void InverseAddRoundKey(
const unsigned int *alpha,
971 for (i=0; i < 4; i++)
974 for (j=0; j < 4; j++)
975 beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
976 ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
977 ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
978 ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
982static inline unsigned int XTime(
unsigned char alpha)
987 beta=(
unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
993static inline unsigned int RotateRight(
const unsigned int x)
995 return((x >> 8) | ((x & 0xff) << 24));
998static void SetAESKey(AESInfo *aes_info,
const StringInfo *key)
1017 assert(aes_info != (AESInfo *) NULL);
1018 assert(aes_info->signature == MagickCoreSignature);
1020 if (IsEventLogging() != MagickFalse)
1021 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
1023 aes_info->rounds=10;
1024 if ((8*GetStringInfoLength(key)) >= 256)
1027 aes_info->rounds=14;
1030 if ((8*GetStringInfoLength(key)) >= 192)
1033 aes_info->rounds=12;
1038 datum=GetStringInfoDatum(aes_info->key);
1039 (void) memset(datum,0,GetStringInfoLength(aes_info->key));
1040 (void) memcpy(datum,GetStringInfoDatum(key),MagickMin(
1041 GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
1042 for (i=0; i < n; i++)
1043 aes_info->encipher_key[i]=(
unsigned int) datum[4*i] |
1044 ((
unsigned int) datum[4*i+1] << 8) |
1045 ((
unsigned int) datum[4*i+2] << 16) |
1046 ((
unsigned int) datum[4*i+3] << 24);
1048 bytes=(AESBlocksize/4)*(aes_info->rounds+1);
1049 for (i=n; i < bytes; i++)
1051 alpha=aes_info->encipher_key[i-1];
1054 alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
1055 beta=XTime((
unsigned char) (beta & 0xff));
1058 if ((n > 6) && ((i % n) == 4))
1059 alpha=ByteSubTransform(alpha,SBox);
1060 aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
1065 for (i=0; i < 4; i++)
1067 aes_info->decipher_key[i]=aes_info->encipher_key[i];
1068 aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
1070 for (i=4; i < (bytes-4); i+=4)
1071 InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
1075 datum=GetStringInfoDatum(aes_info->key);
1076 (void) memset(datum,0,GetStringInfoLength(aes_info->key));
1114MagickExport MagickBooleanType DecipherImage(
Image *image,
1117 assert(image != (
Image *) NULL);
1118 assert(image->signature == MagickCoreSignature);
1120 assert(exception->signature == MagickCoreSignature);
1121 if (IsEventLogging() != MagickFalse)
1122 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1124 ThrowBinaryException(ImageError,
"CipherSupportNotEnabled",image->filename);
1127MagickExport MagickBooleanType PasskeyDecipherImage(
Image *image,
1130 assert(image != (
Image *) NULL);
1131 assert(image->signature == MagickCoreSignature);
1133 assert(exception->signature == MagickCoreSignature);
1134 if (IsEventLogging() != MagickFalse)
1135 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1137 ThrowBinaryException(ImageError,
"CipherSupportNotEnabled",image->filename);
1170MagickExport MagickBooleanType EncipherImage(
Image *image,
1173 assert(image != (
Image *) NULL);
1174 assert(image->signature == MagickCoreSignature);
1176 assert(exception->signature == MagickCoreSignature);
1177 if (IsEventLogging() != MagickFalse)
1178 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1180 ThrowBinaryException(ImageError,
"CipherSupportNotEnabled",image->filename);
1183MagickExport MagickBooleanType PasskeyEncipherImage(
Image *image,
1186 assert(image != (
Image *) NULL);
1187 assert(image->signature == MagickCoreSignature);
1189 assert(exception->signature == MagickCoreSignature);
1190 if (IsEventLogging() != MagickFalse)
1191 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1193 ThrowBinaryException(ImageError,
"CipherSupportNotEnabled",image->filename);