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