1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % CCCC IIIII PPPP H H EEEEE RRRR % 6 % C I P P H H E R R % 7 % C I PPPP HHHHH EEE RRRR % 8 % C I P H H E R R % 9 % CCCC IIIII P H H EEEEE R R % 10 % % 11 % % 12 % MagickCore Cipher Methods % 13 % % 14 % Software Design % 15 % Cristy % 16 % March 2003 % 17 % % 18 % % 19 % Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization % 20 % dedicated to making software imaging solutions freely available. % 21 % % 22 % You may not use this file except in compliance with the License. You may % 23 % obtain a copy of the License at % 24 % % 25 % https://imagemagick.org/script/license.php % 26 % % 27 % Unless required by applicable law or agreed to in writing, software % 28 % distributed under the License is distributed on an "AS IS" BASIS, % 29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 30 % See the License for the specific language governing permissions and % 31 % limitations under the License. % 32 % % 33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34 % 35 % 36 */ 37 38 /* 40 Include declarations. 41 */ 42 #include "MagickCore/studio.h" 43 #include "MagickCore/cache.h" 44 #include "MagickCore/cipher.h" 45 #include "MagickCore/exception.h" 46 #include "MagickCore/exception-private.h" 47 #include "MagickCore/image.h" 48 #include "MagickCore/image-private.h" 49 #include "MagickCore/linked-list.h" 50 #include "MagickCore/list.h" 51 #include "MagickCore/memory_.h" 52 #include "MagickCore/memory-private.h" 53 #include "MagickCore/monitor.h" 54 #include "MagickCore/monitor-private.h" 55 #include "MagickCore/property.h" 56 #include "MagickCore/quantum-private.h" 57 #include "MagickCore/registry.h" 58 #include "MagickCore/semaphore.h" 59 #include "MagickCore/signature-private.h" 60 #include "MagickCore/splay-tree.h" 61 #include "MagickCore/statistic.h" 62 #include "MagickCore/string_.h" 63 64 #if defined(MAGICKCORE_CIPHER_SUPPORT) 66 /* 67 Define declarations. 68 */ 69 #define AESBlocksize 16 70 71 /* 73 Typedef declarations. 74 */ 75 typedef struct _AESInfo 76 { 77 StringInfo 78 *key; 79 80 unsigned int 81 blocksize, 82 *encipher_key, 83 *decipher_key; 84 85 ssize_t 86 rounds, 87 timestamp; 88 89 size_t 90 signature; 91 } AESInfo; 92 93 /* 95 Global declarations. 96 */ 97 static unsigned char 98 InverseLog[256] = 99 { 100 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 101 19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 102 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 103 217, 112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204, 104 79, 209, 104, 184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59, 105 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208, 106 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196, 107 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, 108 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 109 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 110 250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 111 44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126, 112 130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35, 113 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99, 114 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, 69, 207, 115 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, 116 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 117 13, 23, 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 118 199, 82, 246, 1 119 }, 120 Log[256] = 121 { 122 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 123 223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 124 248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 125 166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36, 126 18, 240, 130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208, 127 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253, 48, 128 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110, 129 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186, 130 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 131 167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 132 231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 133 95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236, 134 216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96, 135 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144, 136 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, 83, 57, 137 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171, 138 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 139 227, 165, 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 140 192, 247, 112, 7, 141 }, 142 SBox[256] = 143 { 144 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 145 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 146 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 147 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 148 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 149 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 150 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 151 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 152 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 153 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 154 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 155 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 156 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 157 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 158 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 159 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 160 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 161 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 162 176, 84, 187, 22 163 }; 164 165 /* 167 Forward declarations. 168 */ 169 static AESInfo 170 *DestroyAESInfo(AESInfo *); 171 172 static void 173 EncipherAESBlock(AESInfo *,const unsigned char *,unsigned char *), 174 SetAESKey(AESInfo *,const StringInfo *); 175 176 /* 178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 179 % % 180 % % 181 % % 182 % A c q u i r e A E S I n f o % 183 % % 184 % % 185 % % 186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 187 % 188 % AcquireAESInfo() allocate the AESInfo structure. 189 % 190 % The format of the AcquireAESInfo method is: 191 % 192 % AESInfo *AcquireAESInfo(void) 193 % 194 */ 195 static AESInfo *AcquireAESInfo(void) 196 { 197 AESInfo 198 *aes_info; 199 200 aes_info=(AESInfo *) AcquireCriticalMemory(sizeof(*aes_info)); 201 (void) memset(aes_info,0,sizeof(*aes_info)); 202 aes_info->blocksize=AESBlocksize; 203 aes_info->key=AcquireStringInfo(32); 204 aes_info->encipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof( 205 *aes_info->encipher_key)); 206 aes_info->decipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof( 207 *aes_info->decipher_key)); 208 if ((aes_info->key == (StringInfo *) NULL) || 209 (aes_info->encipher_key == (unsigned int *) NULL) || 210 (aes_info->decipher_key == (unsigned int *) NULL)) 211 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 212 aes_info->timestamp=(ssize_t) time(0); 213 aes_info->signature=MagickCoreSignature; 214 return(aes_info); 215 } 216 217 /* 219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 220 % % 221 % % 222 % % 223 % D e s t r o y A E S I n f o % 224 % % 225 % % 226 % % 227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 228 % 229 % DestroyAESInfo() zeros memory associated with the AESInfo structure. 230 % 231 % The format of the DestroyAESInfo method is: 232 % 233 % AESInfo *DestroyAESInfo(AESInfo *aes_info) 234 % 235 % A description of each parameter follows: 236 % 237 % o aes_info: the cipher context. 238 % 239 */ 240 static AESInfo *DestroyAESInfo(AESInfo *aes_info) 241 { 242 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 243 assert(aes_info != (AESInfo *) NULL); 244 assert(aes_info->signature == MagickCoreSignature); 245 if (aes_info->decipher_key != (unsigned int *) NULL) 246 aes_info->decipher_key=(unsigned int *) RelinquishMagickMemory( 247 aes_info->decipher_key); 248 if (aes_info->encipher_key != (unsigned int *) NULL) 249 aes_info->encipher_key=(unsigned int *) RelinquishMagickMemory( 250 aes_info->encipher_key); 251 if (aes_info->key != (StringInfo *) NULL) 252 aes_info->key=DestroyStringInfo(aes_info->key); 253 aes_info->signature=(~MagickCoreSignature); 254 aes_info=(AESInfo *) RelinquishMagickMemory(aes_info); 255 return(aes_info); 256 } 257 258 /* 260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 261 % % 262 % % 263 % % 264 % E n c i p h e r A E S B l o c k % 265 % % 266 % % 267 % % 268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 269 % 270 % EncipherAESBlock() enciphers a single block of plaintext to produce a block 271 % of ciphertext. 272 % 273 % The format of the EncipherAESBlock method is: 274 % 275 % void EncipherAES(AESInfo *aes_info,const unsigned char *plaintext, 276 % unsigned char *ciphertext) 277 % 278 % A description of each parameter follows: 279 % 280 % o aes_info: the cipher context. 281 % 282 % o plaintext: the plain text. 283 % 284 % o ciphertext: the cipher text. 285 % 286 */ 287 288 static inline void AddRoundKey(const unsigned int *ciphertext, 289 const unsigned int *key,unsigned int *plaintext) 290 { 291 register ssize_t 292 i; 293 294 /* 295 Xor corresponding text input and round key input bytes. 296 */ 297 for (i=0; i < 4; i++) 298 plaintext[i]=key[i] ^ ciphertext[i]; 299 } 300 301 static inline unsigned char ByteMultiply(const unsigned char alpha, 302 const unsigned char beta) 303 { 304 /* 305 Byte multiply two elements of GF(2^m) (mix columns and inverse mix columns). 306 */ 307 if ((alpha == 0) || (beta == 0)) 308 return(0); 309 return(InverseLog[(Log[alpha]+Log[beta]) % 0xff]); 310 } 311 312 static inline unsigned int ByteSubTransform(unsigned int x, 313 unsigned char *s_box) 314 { 315 unsigned int 316 key; 317 318 /* 319 Non-linear layer resists differential and linear cryptoanalysis attacks. 320 */ 321 key=(s_box[x & 0xff]) | (s_box[(x >> 8) & 0xff] << 8) | 322 (s_box[(x >> 16) & 0xff] << 16) | (s_box[(x >> 24) & 0xff] << 24); 323 return(key); 324 } 325 326 static void FinalizeRoundKey(const unsigned int *ciphertext, 327 const unsigned int *key,unsigned char *plaintext) 328 { 329 register unsigned char 330 *p; 331 332 register unsigned int 333 i, 334 j; 335 336 unsigned int 337 value; 338 339 /* 340 The round key is XORed with the result of the mix-column transformation. 341 */ 342 p=plaintext; 343 for (i=0; i < 4; i++) 344 { 345 value=ciphertext[i] ^ key[i]; 346 for (j=0; j < 4; j++) 347 *p++=(unsigned char) ((value >> (8*j)) & 0xff); 348 } 349 /* 350 Reset registers. 351 */ 352 value=0; 353 } 354 355 static void InitializeRoundKey(const unsigned char *ciphertext, 356 const unsigned int *key,unsigned int *plaintext) 357 { 358 register const unsigned char 359 *p; 360 361 register unsigned int 362 i, 363 j; 364 365 unsigned int 366 value; 367 368 p=ciphertext; 369 for (i=0; i < 4; i++) 370 { 371 value=0; 372 for (j=0; j < 4; j++) 373 value|=(*p++ << (8*j)); 374 plaintext[i]=key[i] ^ value; 375 } 376 /* 377 Reset registers. 378 */ 379 value=0; 380 } 381 382 static inline unsigned int RotateLeft(const unsigned int x) 383 { 384 return(((x << 8) | ((x >> 24) & 0xff))); 385 } 386 387 static void EncipherAESBlock(AESInfo *aes_info,const unsigned char *plaintext, 388 unsigned char *ciphertext) 389 { 390 register ssize_t 391 i, 392 j; 393 394 static int 395 map[4][4] = 396 { 397 { 0, 1, 2, 3 }, 398 { 1, 2, 3, 0 }, 399 { 2, 3, 0, 1 }, 400 { 3, 0, 1, 2 } 401 }; 402 403 static unsigned int 404 D[] = 405 { 406 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU, 407 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U, 408 0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU, 409 0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU, 410 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U, 411 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U, 412 0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU, 413 0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U, 414 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U, 415 0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U, 416 0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU, 417 0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU, 418 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U, 419 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU, 420 0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U, 421 0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U, 422 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U, 423 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU, 424 0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U, 425 0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU, 426 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU, 427 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U, 428 0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U, 429 0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U, 430 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U, 431 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U, 432 0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U, 433 0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU, 434 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U, 435 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U, 436 0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU, 437 0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU, 438 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U, 439 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU, 440 0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U, 441 0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU, 442 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U, 443 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U, 444 0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU, 445 0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U, 446 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U, 447 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU, 448 0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U, 449 0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U, 450 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U, 451 0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U, 452 0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U, 453 0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U, 454 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U, 455 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U, 456 0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU, 457 0x3a16162cU 458 }; 459 460 unsigned int 461 alpha, 462 key[4], 463 text[4]; 464 465 /* 466 Encipher one block. 467 */ 468 (void) memset(text,0,sizeof(text)); 469 InitializeRoundKey(plaintext,aes_info->encipher_key,text); 470 for (i=1; i < aes_info->rounds; i++) 471 { 472 /* 473 Linear mixing step: cause diffusion of the bits over multiple rounds. 474 */ 475 for (j=0; j < 4; j++) 476 key[j]=D[text[j] & 0xff] ^ 477 RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^ 478 RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^ 479 RotateLeft(D[(text[map[3][j]] >> 24) & 0xff]))); 480 AddRoundKey(key,aes_info->encipher_key+4*i,text); 481 } 482 for (i=0; i < 4; i++) 483 { 484 alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) | 485 ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000); 486 key[i]=ByteSubTransform(alpha,SBox); 487 } 488 FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext); 489 /* 490 Reset registers. 491 */ 492 alpha=0; 493 (void) memset(key,0,sizeof(key)); 494 (void) memset(text,0,sizeof(text)); 495 } 496 497 /* 499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 500 % % 501 % % 502 % % 503 % P a s s k e y D e c i p h e r I m a g e % 504 % % 505 % % 506 % % 507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 508 % 509 % PasskeyDecipherImage() converts cipher pixels to plain pixels. 510 % 511 % The format of the PasskeyDecipherImage method is: 512 % 513 % MagickBooleanType PasskeyDecipherImage(Image *image, 514 % const StringInfo *passkey,ExceptionInfo *exception) 515 % MagickBooleanType DecipherImage(Image *image,const char *passphrase, 516 % ExceptionInfo *exception) 517 % 518 % A description of each parameter follows: 519 % 520 % o image: the image. 521 % 522 % o passphrase: decipher cipher pixels with this passphrase. 523 % 524 % o passkey: decrypt cipher pixels with this passkey. 525 % 526 % o exception: return any errors or warnings in this structure. 527 % 528 */ 529 530 static inline void IncrementCipherNonce(const size_t length, 531 unsigned char *nonce) 532 { 533 register ssize_t 534 i; 535 536 for (i=(ssize_t) (length-1); i >= 0; i--) 537 { 538 nonce[i]++; 539 if (nonce[i] != 0) 540 return; 541 } 542 ThrowFatalException(ResourceLimitFatalError,"Sequence wrap error `%s'"); 543 } 544 545 MagickExport MagickBooleanType DecipherImage(Image *image, 546 const char *passphrase,ExceptionInfo *exception) 547 { 548 MagickBooleanType 549 status; 550 551 StringInfo 552 *passkey; 553 554 if (passphrase == (const char *) NULL) 555 return(MagickTrue); 556 passkey=StringToStringInfo(passphrase); 557 if (passkey == (StringInfo *) NULL) 558 return(MagickFalse); 559 status=PasskeyDecipherImage(image,passkey,exception); 560 passkey=DestroyStringInfo(passkey); 561 return(status); 562 } 563 564 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image, 565 const StringInfo *passkey,ExceptionInfo *exception) 566 { 567 #define DecipherImageTag "Decipher/Image " 568 569 AESInfo 570 *aes_info; 571 572 CacheView 573 *image_view; 574 575 const unsigned char 576 *digest; 577 578 MagickBooleanType 579 proceed; 580 581 MagickSizeType 582 extent; 583 584 QuantumInfo 585 *quantum_info; 586 587 QuantumType 588 quantum_type; 589 590 SignatureInfo 591 *signature_info; 592 593 register unsigned char 594 *p; 595 596 size_t 597 length; 598 599 ssize_t 600 y; 601 602 StringInfo 603 *key, 604 *nonce; 605 606 unsigned char 607 input_block[AESBlocksize], 608 output_block[AESBlocksize], 609 *pixels; 610 611 /* 612 Generate decipher key and nonce. 613 */ 614 assert(image != (Image *) NULL); 615 assert(image->signature == MagickCoreSignature); 616 if (image->debug != MagickFalse) 617 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 618 assert(exception != (ExceptionInfo *) NULL); 619 assert(exception->signature == MagickCoreSignature); 620 if (passkey == (const StringInfo *) NULL) 621 return(MagickTrue); 622 aes_info=AcquireAESInfo(); 623 key=CloneStringInfo(passkey); 624 if (key == (StringInfo *) NULL) 625 { 626 aes_info=DestroyAESInfo(aes_info); 627 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 628 image->filename); 629 } 630 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2); 631 if (nonce == (StringInfo *) NULL) 632 { 633 key=DestroyStringInfo(key); 634 aes_info=DestroyAESInfo(aes_info); 635 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 636 image->filename); 637 } 638 SetAESKey(aes_info,key); 639 key=DestroyStringInfo(key); 640 signature_info=AcquireSignatureInfo(); 641 UpdateSignature(signature_info,nonce); 642 extent=(MagickSizeType) image->columns*image->rows; 643 SetStringInfoLength(nonce,sizeof(extent)); 644 SetStringInfoDatum(nonce,(const unsigned char *) &extent); 645 UpdateSignature(signature_info,nonce); 646 nonce=DestroyStringInfo(nonce); 647 FinalizeSignature(signature_info); 648 (void) memset(input_block,0,sizeof(input_block)); 649 digest=GetStringInfoDatum(GetSignatureDigest(signature_info)); 650 (void) memcpy(input_block,digest,MagickMin(AESBlocksize, 651 GetSignatureDigestsize(signature_info))*sizeof(*input_block)); 652 signature_info=DestroySignatureInfo(signature_info); 653 /* 654 Convert cipher pixels to plain pixels. 655 */ 656 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image); 657 if (quantum_info == (QuantumInfo *) NULL) 658 { 659 aes_info=DestroyAESInfo(aes_info); 660 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 661 image->filename); 662 } 663 quantum_type=GetQuantumType(image,exception); 664 pixels=(unsigned char *) GetQuantumPixels(quantum_info); 665 image_view=AcquireAuthenticCacheView(image,exception); 666 for (y=0; y < (ssize_t) image->rows; y++) 667 { 668 register ssize_t 669 i, 670 x; 671 672 register Quantum 673 *magick_restrict q; 674 675 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 676 if (q == (Quantum *) NULL) 677 break; 678 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type, 679 pixels,exception); 680 p=pixels; 681 for (x=0; x < (ssize_t) length; x+=AESBlocksize) 682 { 683 (void) memcpy(output_block,input_block,AESBlocksize* 684 sizeof(*output_block)); 685 IncrementCipherNonce(AESBlocksize,input_block); 686 EncipherAESBlock(aes_info,output_block,output_block); 687 for (i=0; i < AESBlocksize; i++) 688 p[i]^=output_block[i]; 689 p+=AESBlocksize; 690 } 691 (void) memcpy(output_block,input_block,AESBlocksize* 692 sizeof(*output_block)); 693 EncipherAESBlock(aes_info,output_block,output_block); 694 for (i=0; x < (ssize_t) length; x++) 695 { 696 p[i]^=output_block[i]; 697 i++; 698 } 699 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type, 700 pixels,exception); 701 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 702 break; 703 proceed=SetImageProgress(image,DecipherImageTag,(MagickOffsetType) y, 704 image->rows); 705 if (proceed == MagickFalse) 706 break; 707 } 708 image_view=DestroyCacheView(image_view); 709 (void) DeleteImageProperty(image,"cipher:type"); 710 (void) DeleteImageProperty(image,"cipher:mode"); 711 (void) DeleteImageProperty(image,"cipher:nonce"); 712 image->taint=MagickFalse; 713 /* 714 Free resources. 715 */ 716 quantum_info=DestroyQuantumInfo(quantum_info); 717 aes_info=DestroyAESInfo(aes_info); 718 (void) memset(input_block,0,sizeof(input_block)); 719 (void) memset(output_block,0,sizeof(output_block)); 720 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse); 721 } 722 723 /* 725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 726 % % 727 % % 728 % % 729 % P a s s k e y E n c i p h e r I m a g e % 730 % % 731 % % 732 % % 733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 734 % 735 % PasskeyEncipherImage() converts pixels to cipher-pixels. 736 % 737 % The format of the PasskeyEncipherImage method is: 738 % 739 % MagickBooleanType PasskeyEncipherImage(Image *image, 740 % const StringInfo *passkey,ExceptionInfo *exception) 741 % MagickBooleanType EncipherImage(Image *image,const char *passphrase, 742 % ExceptionInfo *exception) 743 % 744 % A description of each parameter follows: 745 % 746 % o image: the image. 747 % 748 % o passphrase: encipher pixels with this passphrase. 749 % 750 % o passkey: decrypt cipher pixels with this passkey. 751 % 752 % o exception: return any errors or warnings in this structure. 753 % 754 */ 755 756 MagickExport MagickBooleanType EncipherImage(Image *image, 757 const char *passphrase,ExceptionInfo *exception) 758 { 759 MagickBooleanType 760 status; 761 762 StringInfo 763 *passkey; 764 765 if (passphrase == (const char *) NULL) 766 return(MagickTrue); 767 passkey=StringToStringInfo(passphrase); 768 if (passkey == (StringInfo *) NULL) 769 return(MagickFalse); 770 status=PasskeyEncipherImage(image,passkey,exception); 771 passkey=DestroyStringInfo(passkey); 772 return(status); 773 } 774 775 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image, 776 const StringInfo *passkey,ExceptionInfo *exception) 777 { 778 #define EncipherImageTag "Encipher/Image " 779 780 AESInfo 781 *aes_info; 782 783 CacheView 784 *image_view; 785 786 char 787 *signature; 788 789 const unsigned char 790 *digest; 791 792 MagickBooleanType 793 proceed; 794 795 MagickSizeType 796 extent; 797 798 QuantumInfo 799 *quantum_info; 800 801 QuantumType 802 quantum_type; 803 804 register unsigned char 805 *p; 806 807 SignatureInfo 808 *signature_info; 809 810 size_t 811 length; 812 813 ssize_t 814 y; 815 816 StringInfo 817 *key, 818 *nonce; 819 820 unsigned char 821 input_block[AESBlocksize], 822 output_block[AESBlocksize], 823 *pixels; 824 825 /* 826 Generate encipher key and nonce. 827 */ 828 assert(image != (Image *) NULL); 829 assert(image->signature == MagickCoreSignature); 830 if (image->debug != MagickFalse) 831 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 832 assert(exception != (ExceptionInfo *) NULL); 833 assert(exception->signature == MagickCoreSignature); 834 if (passkey == (const StringInfo *) NULL) 835 return(MagickTrue); 836 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 837 return(MagickFalse); 838 aes_info=AcquireAESInfo(); 839 key=CloneStringInfo(passkey); 840 if (key == (StringInfo *) NULL) 841 { 842 aes_info=DestroyAESInfo(aes_info); 843 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 844 image->filename); 845 } 846 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2); 847 if (nonce == (StringInfo *) NULL) 848 { 849 key=DestroyStringInfo(key); 850 aes_info=DestroyAESInfo(aes_info); 851 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 852 image->filename); 853 } 854 SetAESKey(aes_info,key); 855 key=DestroyStringInfo(key); 856 signature_info=AcquireSignatureInfo(); 857 UpdateSignature(signature_info,nonce); 858 extent=(MagickSizeType) image->columns*image->rows; 859 SetStringInfoLength(nonce,sizeof(extent)); 860 SetStringInfoDatum(nonce,(const unsigned char *) &extent); 861 UpdateSignature(signature_info,nonce); 862 nonce=DestroyStringInfo(nonce); 863 FinalizeSignature(signature_info); 864 signature=StringInfoToHexString(GetSignatureDigest(signature_info)); 865 (void) SetImageProperty(image,"cipher:type","AES",exception); 866 (void) SetImageProperty(image,"cipher:mode","CTR",exception); 867 (void) SetImageProperty(image,"cipher:nonce",signature,exception); 868 signature=DestroyString(signature); 869 (void) memset(input_block,0,sizeof(input_block)); 870 digest=GetStringInfoDatum(GetSignatureDigest(signature_info)); 871 (void) memcpy(input_block,digest,MagickMin(AESBlocksize, 872 GetSignatureDigestsize(signature_info))*sizeof(*input_block)); 873 signature_info=DestroySignatureInfo(signature_info); 874 /* 875 Convert plain pixels to cipher pixels. 876 */ 877 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image); 878 if (quantum_info == (QuantumInfo *) NULL) 879 { 880 aes_info=DestroyAESInfo(aes_info); 881 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 882 image->filename); 883 } 884 quantum_type=GetQuantumType(image,exception); 885 pixels=(unsigned char *) GetQuantumPixels(quantum_info); 886 image_view=AcquireAuthenticCacheView(image,exception); 887 for (y=0; y < (ssize_t) image->rows; y++) 888 { 889 register ssize_t 890 i, 891 x; 892 893 register Quantum 894 *magick_restrict q; 895 896 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 897 if (q == (Quantum *) NULL) 898 break; 899 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type, 900 pixels,exception); 901 p=pixels; 902 for (x=0; x < (ssize_t) length; x+=AESBlocksize) 903 { 904 (void) memcpy(output_block,input_block,AESBlocksize* 905 sizeof(*output_block)); 906 IncrementCipherNonce(AESBlocksize,input_block); 907 EncipherAESBlock(aes_info,output_block,output_block); 908 for (i=0; i < AESBlocksize; i++) 909 p[i]^=output_block[i]; 910 p+=AESBlocksize; 911 } 912 (void) memcpy(output_block,input_block,AESBlocksize* 913 sizeof(*output_block)); 914 EncipherAESBlock(aes_info,output_block,output_block); 915 for (i=0; x < (ssize_t) length; x++) 916 { 917 p[i]^=output_block[i]; 918 i++; 919 } 920 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type, 921 pixels,exception); 922 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 923 break; 924 proceed=SetImageProgress(image,EncipherImageTag,(MagickOffsetType) y, 925 image->rows); 926 if (proceed == MagickFalse) 927 break; 928 } 929 image_view=DestroyCacheView(image_view); 930 image->taint=MagickFalse; 931 /* 932 Free resources. 933 */ 934 quantum_info=DestroyQuantumInfo(quantum_info); 935 aes_info=DestroyAESInfo(aes_info); 936 (void) memset(input_block,0,sizeof(input_block)); 937 (void) memset(output_block,0,sizeof(output_block)); 938 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse); 939 } 940 941 /* 943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 944 % % 945 % % 946 % % 947 % S e t A E S K e y % 948 % % 949 % % 950 % % 951 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 952 % 953 % SetAESKey() sets the key for the AES cipher. The key length is specified 954 % in bits. Valid values are 128, 192, or 256 requiring a key buffer length 955 % in bytes of 16, 24, and 32 respectively. 956 % 957 % The format of the SetAESKey method is: 958 % 959 % SetAESKey(AESInfo *aes_info,const StringInfo *key) 960 % 961 % A description of each parameter follows: 962 % 963 % o aes_info: the cipher context. 964 % 965 % o key: the key. 966 % 967 */ 968 969 static inline void InverseAddRoundKey(const unsigned int *alpha, 970 unsigned int *beta) 971 { 972 register unsigned int 973 i, 974 j; 975 976 for (i=0; i < 4; i++) 977 { 978 beta[i]=0; 979 for (j=0; j < 4; j++) 980 beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^ 981 ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^ 982 ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^ 983 ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j); 984 } 985 } 986 987 static inline unsigned int XTime(unsigned char alpha) 988 { 989 unsigned char 990 beta; 991 992 beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0); 993 alpha<<=1; 994 alpha^=beta; 995 return(alpha); 996 } 997 998 static inline unsigned int RotateRight(const unsigned int x) 999 { 1000 return((x >> 8) | ((x & 0xff) << 24)); 1001 } 1002 1003 static void SetAESKey(AESInfo *aes_info,const StringInfo *key) 1004 { 1005 register ssize_t 1006 i; 1007 1008 ssize_t 1009 bytes, 1010 n; 1011 1012 unsigned char 1013 *datum; 1014 1015 unsigned int 1016 alpha, 1017 beta; 1018 1019 /* 1020 Determine the number of rounds based on the number of bits in key. 1021 */ 1022 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1023 assert(aes_info != (AESInfo *) NULL); 1024 assert(aes_info->signature == MagickCoreSignature); 1025 assert(key != (StringInfo *) NULL); 1026 n=4; 1027 aes_info->rounds=10; 1028 if ((8*GetStringInfoLength(key)) >= 256) 1029 { 1030 n=8; 1031 aes_info->rounds=14; 1032 } 1033 else 1034 if ((8*GetStringInfoLength(key)) >= 192) 1035 { 1036 n=6; 1037 aes_info->rounds=12; 1038 } 1039 /* 1040 Generate crypt key. 1041 */ 1042 datum=GetStringInfoDatum(aes_info->key); 1043 (void) memset(datum,0,GetStringInfoLength(aes_info->key)); 1044 (void) memcpy(datum,GetStringInfoDatum(key),MagickMin( 1045 GetStringInfoLength(key),GetStringInfoLength(aes_info->key))); 1046 for (i=0; i < n; i++) 1047 aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) | 1048 (datum[4*i+2] << 16) | (datum[4*i+3] << 24); 1049 beta=1; 1050 bytes=(AESBlocksize/4)*(aes_info->rounds+1); 1051 for (i=n; i < bytes; i++) 1052 { 1053 alpha=aes_info->encipher_key[i-1]; 1054 if ((i % n) == 0) 1055 { 1056 alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta; 1057 beta=XTime((unsigned char) (beta & 0xff)); 1058 } 1059 else 1060 if ((n > 6) && ((i % n) == 4)) 1061 alpha=ByteSubTransform(alpha,SBox); 1062 aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha; 1063 } 1064 /* 1065 Generate deciper key (in reverse order). 1066 */ 1067 for (i=0; i < 4; i++) 1068 { 1069 aes_info->decipher_key[i]=aes_info->encipher_key[i]; 1070 aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i]; 1071 } 1072 for (i=4; i < (bytes-4); i+=4) 1073 InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i); 1074 /* 1075 Reset registers. 1076 */ 1077 datum=GetStringInfoDatum(aes_info->key); 1078 (void) memset(datum,0,GetStringInfoLength(aes_info->key)); 1079 alpha=0; 1080 beta=0; 1081 } 1082 #else 1083 1084 /* 1086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1087 % % 1088 % % 1089 % % 1090 % P a s s k e y D e c i p h e r I m a g e % 1091 % % 1092 % % 1093 % % 1094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1095 % 1096 % PasskeyDecipherImage() converts cipher pixels to plain pixels. 1097 % 1098 % The format of the PasskeyDecipherImage method is: 1099 % 1100 % MagickBooleanType PasskeyDecipherImage(Image *image, 1101 % const StringInfo *passkey,ExceptionInfo *exception) 1102 % MagickBooleanType DecipherImage(Image *image,const char *passphrase, 1103 % ExceptionInfo *exception) 1104 % 1105 % A description of each parameter follows: 1106 % 1107 % o image: the image. 1108 % 1109 % o passphrase: decipher cipher pixels with this passphrase. 1110 % 1111 % o passkey: decrypt cipher pixels with this passkey. 1112 % 1113 % o exception: return any errors or warnings in this structure. 1114 % 1115 */ 1116 1117 MagickExport MagickBooleanType DecipherImage(Image *image, 1118 const char *passphrase,ExceptionInfo *exception) 1119 { 1120 assert(image != (Image *) NULL); 1121 assert(image->signature == MagickCoreSignature); 1122 if (image->debug != MagickFalse) 1123 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1124 assert(exception != (ExceptionInfo *) NULL); 1125 assert(exception->signature == MagickCoreSignature); 1126 (void) passphrase; 1127 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename); 1128 } 1129 1130 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image, 1131 const StringInfo *passkey,ExceptionInfo *exception) 1132 { 1133 assert(image != (Image *) NULL); 1134 assert(image->signature == MagickCoreSignature); 1135 if (image->debug != MagickFalse) 1136 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1137 assert(exception != (ExceptionInfo *) NULL); 1138 assert(exception->signature == MagickCoreSignature); 1139 (void) passkey; 1140 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename); 1141 } 1142 1143 /* 1145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1146 % % 1147 % % 1148 % % 1149 % P a s s k e y E n c i p h e r I m a g e % 1150 % % 1151 % % 1152 % % 1153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1154 % 1155 % PasskeyEncipherImage() converts pixels to cipher-pixels. 1156 % 1157 % The format of the PasskeyEncipherImage method is: 1158 % 1159 % MagickBooleanType PasskeyEncipherImage(Image *image, 1160 % const StringInfo *passkey,ExceptionInfo *exception) 1161 % MagickBooleanType EncipherImage(Image *image,const char *passphrase, 1162 % ExceptionInfo *exception) 1163 % 1164 % A description of each parameter follows: 1165 % 1166 % o passphrase: decipher cipher pixels with this passphrase. 1167 % 1168 % o passkey: decrypt cipher pixels with this passkey. 1169 % 1170 % o exception: return any errors or warnings in this structure. 1171 % 1172 */ 1173 1174 MagickExport MagickBooleanType EncipherImage(Image *image, 1175 const char *passphrase,ExceptionInfo *exception) 1176 { 1177 assert(image != (Image *) NULL); 1178 assert(image->signature == MagickCoreSignature); 1179 if (image->debug != MagickFalse) 1180 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1181 assert(exception != (ExceptionInfo *) NULL); 1182 assert(exception->signature == MagickCoreSignature); 1183 (void) passphrase; 1184 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename); 1185 } 1186 1187 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image, 1188 const StringInfo *passkey,ExceptionInfo *exception) 1189 { 1190 assert(image != (Image *) NULL); 1191 assert(image->signature == MagickCoreSignature); 1192 if (image->debug != MagickFalse) 1193 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1194 assert(exception != (ExceptionInfo *) NULL); 1195 assert(exception->signature == MagickCoreSignature); 1196 (void) passkey; 1197 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename); 1198 } 1199 #endif 1200