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