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"
61#include "magick/timer-private.h"
63#if defined(MAGICKCORE_CIPHER_SUPPORT)
67#define AESBlocksize 16
72typedef struct _AESInfo
98 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248,
99 19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10,
100 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190,
101 217, 112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204,
102 79, 209, 104, 184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59,
103 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208,
104 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196,
105 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
106 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32,
107 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86,
108 250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237,
109 44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126,
110 130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35,
111 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99,
112 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, 69, 207,
113 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
114 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242,
115 13, 23, 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180,
120 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238,
121 223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200,
122 248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228,
123 166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36,
124 18, 240, 130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208,
125 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253, 48,
126 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110,
127 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
128 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115,
129 167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213,
130 231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245, 89, 203,
131 95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236,
132 216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96,
133 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144,
134 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, 83, 57,
135 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
136 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153,
137 227, 165, 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128,
142 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215,
143 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175,
144 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
145 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154,
146 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
147 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237,
148 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239,
149 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
150 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255,
151 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
152 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238,
153 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92,
154 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213,
155 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46,
156 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
157 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
158 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85,
159 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15,
167 *DestroyAESInfo(AESInfo *);
170 EncipherAESBlock(AESInfo *,
const unsigned char *,
unsigned char *),
191static AESInfo *AcquireAESInfo(
void)
196 aes_info=(AESInfo *) AcquireMagickMemory(
sizeof(*aes_info));
197 if (aes_info == (AESInfo *) NULL)
198 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
199 (void) memset(aes_info,0,
sizeof(*aes_info));
200 aes_info->blocksize=AESBlocksize;
201 aes_info->key=AcquireStringInfo(32);
202 aes_info->encipher_key=(
unsigned int *) AcquireQuantumMemory(60UL,
sizeof(
203 *aes_info->encipher_key));
204 aes_info->decipher_key=(
unsigned int *) AcquireQuantumMemory(60UL,
sizeof(
205 *aes_info->decipher_key));
207 (aes_info->encipher_key == (
unsigned int *) NULL) ||
208 (aes_info->decipher_key == (
unsigned int *) NULL))
209 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
210 aes_info->timestamp=GetMagickTime();
211 aes_info->signature=MagickCoreSignature;
237static AESInfo *DestroyAESInfo(AESInfo *aes_info)
239 assert(aes_info != (AESInfo *) NULL);
240 assert(aes_info->signature == MagickCoreSignature);
241 if (IsEventLogging() != MagickFalse)
242 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
243 if (aes_info->decipher_key != (
unsigned int *) NULL)
244 aes_info->decipher_key=(
unsigned int *) RelinquishMagickMemory(
245 aes_info->decipher_key);
246 if (aes_info->encipher_key != (
unsigned int *) NULL)
247 aes_info->encipher_key=(
unsigned int *) RelinquishMagickMemory(
248 aes_info->encipher_key);
250 aes_info->key=DestroyStringInfo(aes_info->key);
251 aes_info->signature=(~MagickCoreSignature);
252 aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
285static inline void AddRoundKey(
const unsigned int *ciphertext,
286 const unsigned int *key,
unsigned int *plaintext)
294 for (i=0; i < 4; i++)
295 plaintext[i]=key[i] ^ ciphertext[i];
298static inline unsigned int ByteMultiply(
const unsigned char alpha,
299 const unsigned char beta)
304 if ((alpha == 0) || (beta == 0))
306 return((
unsigned int) InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
309static inline unsigned int ByteSubTransform(
unsigned int x,
310 unsigned char *s_box)
318 key=((
unsigned int) s_box[x & 0xff]) |
319 ((
unsigned int) s_box[(x >> 8) & 0xff] << 8) |
320 ((
unsigned int) s_box[(x >> 16) & 0xff] << 16) |
321 ((
unsigned int) s_box[(x >> 24) & 0xff] << 24);
325static void FinalizeRoundKey(
const unsigned int *ciphertext,
326 const unsigned int *key,
unsigned char *plaintext)
342 for (i=0; i < 4; i++)
344 value=ciphertext[i] ^ key[i];
345 for (j=0; j < 4; j++)
346 *p++=(
unsigned char) ((value >> (8*j)) & 0xff);
354static void InitializeRoundKey(
const unsigned char *ciphertext,
355 const unsigned int *key,
unsigned int *plaintext)
368 for (i=0; i < 4; i++)
371 for (j=0; j < 4; j++)
372 value|=((
unsigned int) *p++ << (8*j));
373 plaintext[i]=key[i] ^ value;
381static inline unsigned int RotateLeft(
const unsigned int x)
383 return(((x << 8) | ((x >> 24) & 0xff)));
386static void EncipherAESBlock(AESInfo *aes_info,
const unsigned char *plaintext,
387 unsigned char *ciphertext)
405 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
406 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
407 0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
408 0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
409 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
410 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
411 0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
412 0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
413 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
414 0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
415 0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
416 0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
417 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
418 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
419 0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
420 0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
421 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
422 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
423 0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
424 0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
425 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
426 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
427 0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
428 0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
429 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
430 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
431 0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
432 0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
433 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
434 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
435 0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
436 0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
437 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
438 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
439 0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
440 0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
441 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
442 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
443 0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
444 0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
445 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
446 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
447 0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
448 0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
449 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
450 0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
451 0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
452 0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
453 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
454 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
455 0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
467 (void) memset(text,0,
sizeof(text));
468 InitializeRoundKey(plaintext,aes_info->encipher_key,text);
469 for (i=1; i < aes_info->rounds; i++)
474 for (j=0; j < 4; j++)
475 key[j]=D[text[j] & 0xff] ^
476 RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
477 RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
478 RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
479 AddRoundKey(key,aes_info->encipher_key+4*i,text);
481 for (i=0; i < 4; i++)
483 alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
484 ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
485 key[i]=ByteSubTransform(alpha,SBox);
487 FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
492 (void) ResetMagickMemory(key,0,
sizeof(key));
493 (void) ResetMagickMemory(text,0,
sizeof(text));
528static inline void IncrementCipherNonce(
const size_t length,
529 unsigned char *nonce)
534 for (i=(ssize_t) (length-1); i >= 0; i--)
540 ThrowFatalException(ResourceLimitFatalError,
"Sequence wrap error `%s'");
543MagickExport MagickBooleanType DecipherImage(
Image *image,
552 if (passphrase == (
const char *) NULL)
554 passkey=StringToStringInfo(passphrase);
557 status=PasskeyDecipherImage(image,passkey,exception);
558 passkey=DestroyStringInfo(passkey);
562MagickExport MagickBooleanType PasskeyDecipherImage(
Image *image,
565#define DecipherImageTag "Decipher/Image "
605 input_block[AESBlocksize],
606 output_block[AESBlocksize],
612 assert(image != (
Image *) NULL);
613 assert(image->signature == MagickCoreSignature);
615 assert(exception->signature == MagickCoreSignature);
616 if (IsEventLogging() != MagickFalse)
617 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
620 aes_info=AcquireAESInfo();
621 key=CloneStringInfo(passkey);
624 aes_info=DestroyAESInfo(aes_info);
625 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
628 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
631 key=DestroyStringInfo(key);
632 aes_info=DestroyAESInfo(aes_info);
633 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
636 SetAESKey(aes_info,key);
637 key=DestroyStringInfo(key);
638 signature_info=AcquireSignatureInfo();
639 UpdateSignature(signature_info,nonce);
640 extent=(MagickSizeType) image->columns*image->rows;
641 SetStringInfoLength(nonce,
sizeof(extent));
642 SetStringInfoDatum(nonce,(
const unsigned char *) &extent);
643 UpdateSignature(signature_info,nonce);
644 nonce=DestroyStringInfo(nonce);
645 FinalizeSignature(signature_info);
646 (void) memset(input_block,0,
sizeof(input_block));
647 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
648 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
649 GetSignatureDigestsize(signature_info))*
sizeof(*input_block));
650 signature_info=DestroySignatureInfo(signature_info);
654 quantum_info=AcquireQuantumInfo((
const ImageInfo *) NULL,image);
657 aes_info=DestroyAESInfo(aes_info);
658 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
661 quantum_type=GetQuantumType(image,exception);
662 pixels=GetQuantumPixels(quantum_info);
663 image_view=AcquireAuthenticCacheView(image,exception);
664 for (y=0; y < (ssize_t) image->rows; y++)
673 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
676 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
679 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
681 (void) memmove(output_block,input_block,AESBlocksize*
682 sizeof(*output_block));
683 IncrementCipherNonce(AESBlocksize,input_block);
684 EncipherAESBlock(aes_info,output_block,output_block);
685 for (i=0; i < AESBlocksize; i++)
686 p[i]^=output_block[i];
687 p+=(ptrdiff_t) AESBlocksize;
689 (void) memmove(output_block,input_block,AESBlocksize*
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) == 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 (void) memset(input_block,0,
sizeof(input_block));
861 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
862 (void) memcpy(input_block,digest,MagickMin(AESBlocksize,
863 GetSignatureDigestsize(signature_info))*
sizeof(*input_block));
864 signature=StringInfoToHexString(GetSignatureDigest(signature_info));
865 (void) SetImageProperty(image,
"cipher:type",
"AES");
866 (void) SetImageProperty(image,
"cipher:mode",
"CTR");
867 (void) SetImageProperty(image,
"cipher:nonce",signature);
868 signature=DestroyString(signature);
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=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);
895 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
898 for (x=0; x < (ssize_t) length; x+=AESBlocksize)
900 (void) memmove(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) memmove(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);