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