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