blob: ca8086b860b8577e87baeef13edadd299e6ddf47 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% John Cristy %
16% March 2003 %
17% %
18% %
cristy1454be72011-12-19 01:52:48 +000019% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000020% 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*/
cristy4c08aed2011-07-01 19:47:50 +000041#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/hashmap.h"
47#include "MagickCore/image.h"
48#include "MagickCore/image-private.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"
cristy3ed852e2009-09-05 21:47:34 +000061
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{
73 StringInfo
74 *key;
75
76 unsigned int
77 blocksize,
78 *encipher_key,
79 *decipher_key;
80
cristybb503372010-05-27 20:51:26 +000081 ssize_t
cristy3ed852e2009-09-05 21:47:34 +000082 rounds,
83 timestamp;
84
cristybb503372010-05-27 20:51:26 +000085 size_t
cristy3ed852e2009-09-05 21:47:34 +000086 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
cristy73bd4a52010-10-05 11:24:23 +0000193 aes_info=(AESInfo *) AcquireMagickMemory(sizeof(*aes_info));
cristy3ed852e2009-09-05 21:47:34 +0000194 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");
cristybb503372010-05-27 20:51:26 +0000207 aes_info->timestamp=(ssize_t) time(0);
cristy3ed852e2009-09-05 21:47:34 +0000208 aes_info->signature=MagickSignature;
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 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
237 assert(aes_info != (AESInfo *) NULL);
238 assert(aes_info->signature == MagickSignature);
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=(~MagickSignature);
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
281static inline void AddRoundKey(const unsigned int *ciphertext,
282 const unsigned int *key,unsigned int *plaintext)
283{
cristybb503372010-05-27 20:51:26 +0000284 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000285 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
294static 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
305static 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
319static 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++)
cristyaa83c2c2011-09-21 13:36:25 +0000340 *p++=(unsigned char) ((value >> (8*j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +0000341 }
342 /*
343 Reset registers.
344 */
345 value=0;
346}
347
348static 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
375static inline unsigned int RotateLeft(const unsigned int x)
376{
377 return(((x << 8) | ((x >> 24) & 0xff)));
378}
379
380static void EncipherAESBlock(AESInfo *aes_info,const unsigned char *plaintext,
381 unsigned char *ciphertext)
382{
cristybb503372010-05-27 20:51:26 +0000383 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000384 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
522static inline size_t MagickMin(const size_t x,const size_t y)
523{
524 if (x < y)
525 return(x);
526 return(y);
527}
528
529MagickExport MagickBooleanType DecipherImage(Image *image,
530 const char *passphrase,ExceptionInfo *exception)
531{
532 MagickBooleanType
533 status;
534
535 StringInfo
536 *passkey;
537
538 if (passphrase == (const char *) NULL)
539 return(MagickTrue);
540 passkey=StringToStringInfo(passphrase);
541 if (passkey == (StringInfo *) NULL)
542 return(MagickFalse);
543 status=PasskeyDecipherImage(image,passkey,exception);
544 passkey=DestroyStringInfo(passkey);
545 return(status);
546}
547
548MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
549 const StringInfo *passkey,ExceptionInfo *exception)
550{
551#define DecipherImageTag "Decipher/Image "
552
553 AESInfo
554 *aes_info;
555
cristyc4c8d132010-01-07 01:58:38 +0000556 CacheView
557 *image_view;
558
cristy3ed852e2009-09-05 21:47:34 +0000559 const unsigned char
560 *digest;
561
cristy3ed852e2009-09-05 21:47:34 +0000562 MagickBooleanType
563 proceed;
564
565 QuantumInfo
566 *quantum_info;
567
568 QuantumType
569 quantum_type;
570
571 SignatureInfo
572 *signature_info;
573
574 register unsigned char
575 *p;
576
577 size_t
578 length;
579
cristy9d314ff2011-03-09 01:30:28 +0000580 ssize_t
581 y;
582
cristy3ed852e2009-09-05 21:47:34 +0000583 StringInfo
584 *key,
585 *nonce;
586
587 unsigned char
588 input_block[AESBlocksize],
589 output_block[AESBlocksize],
590 *pixels;
591
cristy3ed852e2009-09-05 21:47:34 +0000592 /*
593 Generate decipher key and nonce.
594 */
595 assert(image != (Image *) NULL);
596 assert(image->signature == MagickSignature);
597 if (image->debug != MagickFalse)
598 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
599 assert(exception != (ExceptionInfo *) NULL);
600 assert(exception->signature == MagickSignature);
601 if (passkey == (const StringInfo *) NULL)
602 return(MagickTrue);
603 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
604 if (quantum_info == (QuantumInfo *) NULL)
605 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
606 image->filename);
607 aes_info=AcquireAESInfo();
608 key=CloneStringInfo(passkey);
609 if (key == (StringInfo *) NULL)
610 {
611 aes_info=DestroyAESInfo(aes_info);
612 quantum_info=DestroyQuantumInfo(quantum_info);
613 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
614 image->filename);
615 }
cristy9a903202012-06-11 01:08:56 +0000616 SetAESKey(aes_info,key);
617 key=DestroyStringInfo(key);
618 nonce=AcquireStringInfo(0);
cristy3ed852e2009-09-05 21:47:34 +0000619 if (nonce == (StringInfo *) NULL)
620 {
621 key=DestroyStringInfo(key);
622 aes_info=DestroyAESInfo(aes_info);
623 quantum_info=DestroyQuantumInfo(quantum_info);
624 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
625 image->filename);
626 }
cristy3ed852e2009-09-05 21:47:34 +0000627 signature_info=AcquireSignatureInfo();
cristy3ed852e2009-09-05 21:47:34 +0000628 SetStringInfoLength(nonce,sizeof(quantum_info->extent));
629 SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
630 UpdateSignature(signature_info,nonce);
631 FinalizeSignature(signature_info);
632 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
633 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
634 (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
635 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
636 nonce=DestroyStringInfo(nonce);
637 signature_info=DestroySignatureInfo(signature_info);
638 /*
639 Convert cipher pixels to plain pixels.
640 */
641 quantum_type=GetQuantumType(image,exception);
642 pixels=GetQuantumPixels(quantum_info);
cristydb070952012-04-20 14:33:00 +0000643 image_view=AcquireAuthenticCacheView(image,exception);
cristybb503372010-05-27 20:51:26 +0000644 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000645 {
cristybb503372010-05-27 20:51:26 +0000646 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000647 x;
648
cristy4c08aed2011-07-01 19:47:50 +0000649 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000650 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000651
652 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000653 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000654 break;
cristy3ed852e2009-09-05 21:47:34 +0000655 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
656 pixels,exception);
657 p=pixels;
cristybb503372010-05-27 20:51:26 +0000658 for (x=0; x < (ssize_t) length; x++)
cristy3ed852e2009-09-05 21:47:34 +0000659 {
660 (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
661 sizeof(*output_block));
662 EncipherAESBlock(aes_info,output_block,output_block);
663 (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
664 sizeof(*input_block));
665 input_block[AESBlocksize-1]=(*p);
666 *p++^=(*output_block);
667 }
668 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
669 pixels,exception);
670 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
671 break;
cristybb503372010-05-27 20:51:26 +0000672 proceed=SetImageProgress(image,DecipherImageTag,(MagickOffsetType) y,
673 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000674 if (proceed == MagickFalse)
675 break;
676 }
677 image_view=DestroyCacheView(image_view);
678 (void) DeleteImageProperty(image,"cipher:type");
679 (void) DeleteImageProperty(image,"cipher:mode");
680 (void) DeleteImageProperty(image,"cipher:nonce");
681 image->taint=MagickFalse;
682 /*
683 Free resources.
684 */
685 quantum_info=DestroyQuantumInfo(quantum_info);
686 aes_info=DestroyAESInfo(aes_info);
687 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
688 (void) ResetMagickMemory(output_block,0,sizeof(output_block));
cristybb503372010-05-27 20:51:26 +0000689 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +0000690}
691
692/*
693%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
694% %
695% %
696% %
697% P a s s k e y E n c i p h e r I m a g e %
698% %
699% %
700% %
701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
702%
703% PasskeyEncipherImage() converts pixels to cipher-pixels.
704%
705% The format of the PasskeyEncipherImage method is:
706%
707% MagickBooleanType PasskeyEncipherImage(Image *image,
708% const StringInfo *passkey,ExceptionInfo *exception)
709% MagickBooleanType EncipherImage(Image *image,const char *passphrase,
710% ExceptionInfo *exception)
711%
712% A description of each parameter follows:
713%
714% o image: the image.
715%
716% o passphrase: encipher pixels with this passphrase.
717%
718% o passkey: decrypt cipher pixels with this passkey.
719%
720% o exception: return any errors or warnings in this structure.
721%
722*/
723
724MagickExport MagickBooleanType EncipherImage(Image *image,
725 const char *passphrase,ExceptionInfo *exception)
726{
727 MagickBooleanType
728 status;
729
730 StringInfo
731 *passkey;
732
733 if (passphrase == (const char *) NULL)
734 return(MagickTrue);
735 passkey=StringToStringInfo(passphrase);
736 if (passkey == (StringInfo *) NULL)
737 return(MagickFalse);
738 status=PasskeyEncipherImage(image,passkey,exception);
739 passkey=DestroyStringInfo(passkey);
740 return(status);
741}
742
743MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
744 const StringInfo *passkey,ExceptionInfo *exception)
745{
746#define EncipherImageTag "Encipher/Image "
747
748 AESInfo
749 *aes_info;
750
cristyc4c8d132010-01-07 01:58:38 +0000751 CacheView
752 *image_view;
753
cristy3ed852e2009-09-05 21:47:34 +0000754 char
755 *signature;
756
757 const unsigned char
758 *digest;
759
cristy3ed852e2009-09-05 21:47:34 +0000760 MagickBooleanType
761 proceed;
762
763 QuantumInfo
764 *quantum_info;
765
766 QuantumType
767 quantum_type;
768
769 register unsigned char
770 *p;
771
772 SignatureInfo
773 *signature_info;
774
775 size_t
776 length;
777
cristy9d314ff2011-03-09 01:30:28 +0000778 ssize_t
779 y;
780
cristy3ed852e2009-09-05 21:47:34 +0000781 StringInfo
782 *key,
783 *nonce;
784
785 unsigned char
786 input_block[AESBlocksize],
787 output_block[AESBlocksize],
788 *pixels;
789
cristy3ed852e2009-09-05 21:47:34 +0000790 /*
791 Generate encipher key and nonce.
792 */
793 assert(image != (Image *) NULL);
794 assert(image->signature == MagickSignature);
795 if (image->debug != MagickFalse)
796 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
797 assert(exception != (ExceptionInfo *) NULL);
798 assert(exception->signature == MagickSignature);
799 if (passkey == (const StringInfo *) NULL)
800 return(MagickTrue);
cristy574cc262011-08-05 01:23:58 +0000801 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000802 return(MagickFalse);
803 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
804 if (quantum_info == (QuantumInfo *) NULL)
805 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
806 image->filename);
807 aes_info=AcquireAESInfo();
808 key=CloneStringInfo(passkey);
809 if (key == (StringInfo *) NULL)
810 {
811 aes_info=DestroyAESInfo(aes_info);
812 quantum_info=DestroyQuantumInfo(quantum_info);
813 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
814 image->filename);
815 }
cristy9a903202012-06-11 01:08:56 +0000816 SetAESKey(aes_info,key);
817 key=DestroyStringInfo(key);
818 nonce=AcquireStringInfo(0);
cristy3ed852e2009-09-05 21:47:34 +0000819 if (nonce == (StringInfo *) NULL)
820 {
821 key=DestroyStringInfo(key);
822 aes_info=DestroyAESInfo(aes_info);
823 quantum_info=DestroyQuantumInfo(quantum_info);
824 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
825 image->filename);
826 }
cristy3ed852e2009-09-05 21:47:34 +0000827 signature_info=AcquireSignatureInfo();
cristy3ed852e2009-09-05 21:47:34 +0000828 SetStringInfoLength(nonce,sizeof(quantum_info->extent));
829 SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
830 UpdateSignature(signature_info,nonce);
831 nonce=DestroyStringInfo(nonce);
832 FinalizeSignature(signature_info);
833 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
834 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
835 (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
836 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
837 signature=StringInfoToHexString(GetSignatureDigest(signature_info));
cristyd15e6592011-10-15 00:13:06 +0000838 (void) SetImageProperty(image,"cipher:type","AES",exception);
839 (void) SetImageProperty(image,"cipher:mode","CFB",exception);
840 (void) SetImageProperty(image,"cipher:nonce",signature,exception);
cristy3ed852e2009-09-05 21:47:34 +0000841 signature=DestroyString(signature);
842 signature_info=DestroySignatureInfo(signature_info);
843 /*
844 Convert plain pixels to cipher pixels.
845 */
846 quantum_type=GetQuantumType(image,exception);
847 pixels=GetQuantumPixels(quantum_info);
cristydb070952012-04-20 14:33:00 +0000848 image_view=AcquireAuthenticCacheView(image,exception);
cristybb503372010-05-27 20:51:26 +0000849 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000850 {
cristybb503372010-05-27 20:51:26 +0000851 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000852 x;
853
cristy4c08aed2011-07-01 19:47:50 +0000854 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000855 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000856
857 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000858 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000859 break;
cristy3ed852e2009-09-05 21:47:34 +0000860 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
861 pixels,exception);
862 p=pixels;
cristybb503372010-05-27 20:51:26 +0000863 for (x=0; x < (ssize_t) length; x++)
cristy3ed852e2009-09-05 21:47:34 +0000864 {
865 (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
866 sizeof(*output_block));
867 EncipherAESBlock(aes_info,output_block,output_block);
868 *p^=(*output_block);
869 (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
870 sizeof(*input_block));
871 input_block[AESBlocksize-1]=(*p++);
872 }
873 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
874 pixels,exception);
875 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
876 break;
cristybb503372010-05-27 20:51:26 +0000877 proceed=SetImageProgress(image,EncipherImageTag,(MagickOffsetType) y,
878 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000879 if (proceed == MagickFalse)
880 break;
881 }
882 image_view=DestroyCacheView(image_view);
883 image->taint=MagickFalse;
884 /*
885 Free resources.
886 */
887 quantum_info=DestroyQuantumInfo(quantum_info);
888 aes_info=DestroyAESInfo(aes_info);
889 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
890 (void) ResetMagickMemory(output_block,0,sizeof(output_block));
cristybb503372010-05-27 20:51:26 +0000891 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +0000892}
893
894/*
895%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
896% %
897% %
898% %
899% S e t A E S K e y %
900% %
901% %
902% %
903%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
904%
905% SetAESKey() sets the key for the AES cipher. The key length is specified
906% in bits. Valid values are 128, 192, or 256 requiring a key buffer length
907% in bytes of 16, 24, and 32 respectively.
908%
909% The format of the SetAESKey method is:
910%
911% SetAESKey(AESInfo *aes_info,const StringInfo *key)
912%
913% A description of each parameter follows:
914%
915% o aes_info: the cipher context.
916%
917% o key: the key.
918%
919*/
920
921static inline void InverseAddRoundKey(const unsigned int *alpha,
922 unsigned int *beta)
923{
924 register unsigned int
925 i,
926 j;
927
928 for (i=0; i < 4; i++)
929 {
930 beta[i]=0;
931 for (j=0; j < 4; j++)
932 beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
933 ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
934 ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
935 ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
936 }
937}
938
939static inline unsigned int XTime(unsigned char alpha)
940{
941 unsigned char
942 beta;
943
944 beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
945 alpha<<=1;
946 alpha^=beta;
947 return(alpha);
948}
949
950static inline unsigned int RotateRight(const unsigned int x)
951{
952 return((x >> 8) | ((x & 0xff) << 24));
953}
954
955static void SetAESKey(AESInfo *aes_info,const StringInfo *key)
956{
cristy9d314ff2011-03-09 01:30:28 +0000957 register ssize_t
958 i;
959
cristybb503372010-05-27 20:51:26 +0000960 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000961 bytes,
962 n;
963
cristy3ed852e2009-09-05 21:47:34 +0000964 unsigned char
965 *datum;
966
967 unsigned int
968 alpha,
969 beta;
970
971 /*
972 Determine the number of rounds based on the number of bits in key.
973 */
974 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
975 assert(aes_info != (AESInfo *) NULL);
976 assert(aes_info->signature == MagickSignature);
977 assert(key != (StringInfo *) NULL);
978 n=4;
979 aes_info->rounds=10;
980 if ((8*GetStringInfoLength(key)) >= 256)
981 {
982 n=8;
983 aes_info->rounds=14;
984 }
985 else
986 if ((8*GetStringInfoLength(key)) >= 192)
987 {
988 n=6;
989 aes_info->rounds=12;
990 }
991 /*
992 Generate crypt key.
993 */
994 datum=GetStringInfoDatum(aes_info->key);
995 (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
996 (void) CopyMagickMemory(datum,GetStringInfoDatum(key),MagickMin(
997 GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
998 for (i=0; i < n; i++)
999 aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) |
1000 (datum[4*i+2] << 16) | (datum[4*i+3] << 24);
1001 beta=1;
1002 bytes=(AESBlocksize/4)*(aes_info->rounds+1);
1003 for (i=n; i < bytes; i++)
1004 {
1005 alpha=aes_info->encipher_key[i-1];
1006 if ((i % n) == 0)
1007 {
1008 alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
1009 beta=XTime((unsigned char) (beta & 0xff));
1010 }
1011 else
1012 if ((n > 6) && ((i % n) == 4))
1013 alpha=ByteSubTransform(alpha,SBox);
1014 aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
1015 }
1016 /*
1017 Generate deciper key (in reverse order).
1018 */
1019 for (i=0; i < 4; i++)
1020 {
1021 aes_info->decipher_key[i]=aes_info->encipher_key[i];
1022 aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
1023 }
1024 for (i=4; i < (bytes-4); i+=4)
1025 InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
1026 /*
1027 Reset registers.
1028 */
1029 datum=GetStringInfoDatum(aes_info->key);
1030 (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
1031 alpha=0;
1032 beta=0;
1033}
1034#else
1035
1036/*
1037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038% %
1039% %
1040% %
1041% P a s s k e y D e c i p h e r I m a g e %
1042% %
1043% %
1044% %
1045%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046%
1047% PasskeyDecipherImage() converts cipher pixels to plain pixels.
1048%
1049% The format of the PasskeyDecipherImage method is:
1050%
1051% MagickBooleanType PasskeyDecipherImage(Image *image,
1052% const StringInfo *passkey,ExceptionInfo *exception)
1053% MagickBooleanType DecipherImage(Image *image,const char *passphrase,
1054% ExceptionInfo *exception)
1055%
1056% A description of each parameter follows:
1057%
1058% o image: the image.
1059%
1060% o passphrase: decipher cipher pixels with this passphrase.
1061%
1062% o passkey: decrypt cipher pixels with this passkey.
1063%
1064% o exception: return any errors or warnings in this structure.
1065%
1066*/
1067
1068MagickExport MagickBooleanType DecipherImage(Image *image,
1069 const char *passphrase,ExceptionInfo *exception)
1070{
1071 assert(image != (Image *) NULL);
1072 assert(image->signature == MagickSignature);
1073 if (image->debug != MagickFalse)
1074 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1075 assert(exception != (ExceptionInfo *) NULL);
1076 assert(exception->signature == MagickSignature);
1077 (void) passphrase;
1078 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1079}
1080
1081MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
1082 const StringInfo *passkey,ExceptionInfo *exception)
1083{
1084 assert(image != (Image *) NULL);
1085 assert(image->signature == MagickSignature);
1086 if (image->debug != MagickFalse)
1087 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1088 assert(exception != (ExceptionInfo *) NULL);
1089 assert(exception->signature == MagickSignature);
1090 (void) passkey;
1091 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1092}
1093
1094/*
1095%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1096% %
1097% %
1098% %
1099% P a s s k e y E n c i p h e r I m a g e %
1100% %
1101% %
1102% %
1103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1104%
1105% PasskeyEncipherImage() converts pixels to cipher-pixels.
1106%
1107% The format of the PasskeyEncipherImage method is:
1108%
1109% MagickBooleanType PasskeyEncipherImage(Image *image,
1110% const StringInfo *passkey,ExceptionInfo *exception)
1111% MagickBooleanType EncipherImage(Image *image,const char *passphrase,
1112% ExceptionInfo *exception)
1113%
1114% A description of each parameter follows:
1115%
1116% o passphrase: decipher cipher pixels with this passphrase.
1117%
1118% o passkey: decrypt cipher pixels with this passkey.
1119%
1120% o exception: return any errors or warnings in this structure.
1121%
1122*/
1123
1124MagickExport MagickBooleanType EncipherImage(Image *image,
1125 const char *passphrase,ExceptionInfo *exception)
1126{
1127 assert(image != (Image *) NULL);
1128 assert(image->signature == MagickSignature);
1129 if (image->debug != MagickFalse)
1130 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1131 assert(exception != (ExceptionInfo *) NULL);
1132 assert(exception->signature == MagickSignature);
1133 (void) passphrase;
1134 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1135}
1136
1137MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
1138 const StringInfo *passkey,ExceptionInfo *exception)
1139{
1140 assert(image != (Image *) NULL);
1141 assert(image->signature == MagickSignature);
1142 if (image->debug != MagickFalse)
1143 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1144 assert(exception != (ExceptionInfo *) NULL);
1145 assert(exception->signature == MagickSignature);
1146 (void) passkey;
1147 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
1148}
1149#endif