00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "magick/studio.h"
00042 #include "magick/cache.h"
00043 #include "magick/cipher.h"
00044 #include "magick/exception.h"
00045 #include "magick/exception-private.h"
00046 #include "magick/hashmap.h"
00047 #include "magick/image.h"
00048 #include "magick/image-private.h"
00049 #include "magick/list.h"
00050 #include "magick/memory_.h"
00051 #include "magick/monitor.h"
00052 #include "magick/monitor-private.h"
00053 #include "magick/property.h"
00054 #include "magick/quantum-private.h"
00055 #include "magick/registry.h"
00056 #include "magick/semaphore.h"
00057 #include "magick/signature-private.h"
00058 #include "magick/splay-tree.h"
00059 #include "magick/statistic.h"
00060 #include "magick/string_.h"
00061
00062 #if defined(MAGICKCORE_CIPHER_SUPPORT)
00063
00064
00065
00066 #define AESBlocksize 16
00067
00068
00069
00070
00071 typedef struct _AESInfo
00072 {
00073 StringInfo
00074 *key;
00075
00076 unsigned int
00077 blocksize,
00078 *encipher_key,
00079 *decipher_key;
00080
00081 long
00082 rounds,
00083 timestamp;
00084
00085 unsigned long
00086 signature;
00087 } AESInfo;
00088
00089
00090
00091
00092 static unsigned char
00093 InverseLog[256] =
00094 {
00095 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248,
00096 19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10,
00097 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190,
00098 217, 112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204,
00099 79, 209, 104, 184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59,
00100 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208,
00101 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196,
00102 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
00103 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32,
00104 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86,
00105 250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237,
00106 44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126,
00107 130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35,
00108 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99,
00109 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, 69, 207,
00110 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
00111 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242,
00112 13, 23, 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180,
00113 199, 82, 246, 1
00114 },
00115 Log[256] =
00116 {
00117 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238,
00118 223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200,
00119 248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228,
00120 166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36,
00121 18, 240, 130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208,
00122 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253, 48,
00123 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110,
00124 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
00125 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115,
00126 167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213,
00127 231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245, 89, 203,
00128 95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236,
00129 216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96,
00130 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144,
00131 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, 83, 57,
00132 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
00133 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153,
00134 227, 165, 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128,
00135 192, 247, 112, 7,
00136 },
00137 SBox[256] =
00138 {
00139 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215,
00140 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175,
00141 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
00142 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154,
00143 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
00144 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237,
00145 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239,
00146 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
00147 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255,
00148 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
00149 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238,
00150 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92,
00151 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213,
00152 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46,
00153 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
00154 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
00155 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85,
00156 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15,
00157 176, 84, 187, 22
00158 };
00159
00160
00161
00162
00163 static AESInfo
00164 *DestroyAESInfo(AESInfo *);
00165
00166 static void
00167 EncipherAESBlock(AESInfo *,const unsigned char *,unsigned char *),
00168 SetAESKey(AESInfo *,const StringInfo *);
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 static AESInfo *AcquireAESInfo(void)
00189 {
00190 AESInfo
00191 *aes_info;
00192
00193 aes_info=(AESInfo *) AcquireMagickMemory(sizeof(*aes_info));
00194 if (aes_info == (AESInfo *) NULL)
00195 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00196 (void) ResetMagickMemory(aes_info,0,sizeof(*aes_info));
00197 aes_info->blocksize=AESBlocksize;
00198 aes_info->key=AcquireStringInfo(32);
00199 aes_info->encipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
00200 *aes_info->encipher_key));
00201 aes_info->decipher_key=(unsigned int *) AcquireQuantumMemory(60UL,sizeof(
00202 *aes_info->decipher_key));
00203 if ((aes_info->key == (StringInfo *) NULL) ||
00204 (aes_info->encipher_key == (unsigned int *) NULL) ||
00205 (aes_info->decipher_key == (unsigned int *) NULL))
00206 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00207 aes_info->timestamp=(long) time(0);
00208 aes_info->signature=MagickSignature;
00209 return(aes_info);
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 static AESInfo *DestroyAESInfo(AESInfo *aes_info)
00235 {
00236 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00237 assert(aes_info != (AESInfo *) NULL);
00238 assert(aes_info->signature == MagickSignature);
00239 if (aes_info->decipher_key != (unsigned int *) NULL)
00240 aes_info->decipher_key=(unsigned int *) RelinquishMagickMemory(
00241 aes_info->decipher_key);
00242 if (aes_info->encipher_key != (unsigned int *) NULL)
00243 aes_info->encipher_key=(unsigned int *) RelinquishMagickMemory(
00244 aes_info->encipher_key);
00245 if (aes_info->key != (StringInfo *) NULL)
00246 aes_info->key=DestroyStringInfo(aes_info->key);
00247 aes_info->signature=(~MagickSignature);
00248 aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
00249 return(aes_info);
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 static inline void AddRoundKey(const unsigned int *ciphertext,
00282 const unsigned int *key,unsigned int *plaintext)
00283 {
00284 register long
00285 i;
00286
00287
00288
00289
00290 for (i=0; i < 4; i++)
00291 plaintext[i]=key[i] ^ ciphertext[i];
00292 }
00293
00294 static inline unsigned char ByteMultiply(const unsigned char alpha,
00295 const unsigned char beta)
00296 {
00297
00298
00299
00300 if ((alpha == 0) || (beta == 0))
00301 return(0);
00302 return(InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
00303 }
00304
00305 static inline unsigned int ByteSubTransform(unsigned int x,
00306 unsigned char *s_box)
00307 {
00308 unsigned int
00309 key;
00310
00311
00312
00313
00314 key=(s_box[x & 0xff]) | (s_box[(x >> 8) & 0xff] << 8) |
00315 (s_box[(x >> 16) & 0xff] << 16) | (s_box[(x >> 24) & 0xff] << 24);
00316 return(key);
00317 }
00318
00319 static void FinalizeRoundKey(const unsigned int *ciphertext,
00320 const unsigned int *key,unsigned char *plaintext)
00321 {
00322 register unsigned char
00323 *p;
00324
00325 register unsigned int
00326 i,
00327 j;
00328
00329 unsigned int
00330 value;
00331
00332
00333
00334
00335 p=plaintext;
00336 for (i=0; i < 4; i++)
00337 {
00338 value=ciphertext[i] ^ key[i];
00339 for (j=0; j < 4; j++)
00340 *p++=(value >> (8*j)) & 0xff;
00341 }
00342
00343
00344
00345 value=0;
00346 }
00347
00348 static void InitializeRoundKey(const unsigned char *ciphertext,
00349 const unsigned int *key,unsigned int *plaintext)
00350 {
00351 register const unsigned char
00352 *p;
00353
00354 register unsigned int
00355 i,
00356 j;
00357
00358 unsigned int
00359 value;
00360
00361 p=ciphertext;
00362 for (i=0; i < 4; i++)
00363 {
00364 value=0;
00365 for (j=0; j < 4; j++)
00366 value|=(*p++ << (8*j));
00367 plaintext[i]=key[i] ^ value;
00368 }
00369
00370
00371
00372 value=0;
00373 }
00374
00375 static inline unsigned int RotateLeft(const unsigned int x)
00376 {
00377 return(((x << 8) | ((x >> 24) & 0xff)));
00378 }
00379
00380 static void EncipherAESBlock(AESInfo *aes_info,const unsigned char *plaintext,
00381 unsigned char *ciphertext)
00382 {
00383 register long
00384 i,
00385 j;
00386
00387 static int
00388 map[4][4] =
00389 {
00390 { 0, 1, 2, 3 },
00391 { 1, 2, 3, 0 },
00392 { 2, 3, 0, 1 },
00393 { 3, 0, 1, 2 }
00394 };
00395
00396 static unsigned int
00397 D[] =
00398 {
00399 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
00400 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
00401 0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
00402 0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
00403 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
00404 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
00405 0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
00406 0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
00407 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
00408 0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
00409 0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
00410 0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
00411 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
00412 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
00413 0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
00414 0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
00415 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
00416 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
00417 0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
00418 0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
00419 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
00420 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
00421 0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
00422 0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
00423 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
00424 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
00425 0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
00426 0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
00427 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
00428 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
00429 0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
00430 0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
00431 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
00432 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
00433 0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
00434 0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
00435 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
00436 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
00437 0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
00438 0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
00439 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
00440 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
00441 0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
00442 0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
00443 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
00444 0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
00445 0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
00446 0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
00447 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
00448 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
00449 0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
00450 0x3a16162cU
00451 };
00452
00453 unsigned int
00454 alpha,
00455 key[4],
00456 text[4];
00457
00458
00459
00460
00461 (void) memset(text,0,sizeof(text));
00462 InitializeRoundKey(plaintext,aes_info->encipher_key,text);
00463 for (i=1; i < aes_info->rounds; i++)
00464 {
00465
00466
00467
00468 for (j=0; j < 4; j++)
00469 key[j]=D[text[j] & 0xff] ^
00470 RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
00471 RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
00472 RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
00473 AddRoundKey(key,aes_info->encipher_key+4*i,text);
00474 }
00475 for (i=0; i < 4; i++)
00476 {
00477 alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
00478 ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
00479 key[i]=ByteSubTransform(alpha,SBox);
00480 }
00481 FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
00482
00483
00484
00485 alpha=0;
00486 (void) ResetMagickMemory(key,0,sizeof(key));
00487 (void) ResetMagickMemory(text,0,sizeof(text));
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 static inline size_t MagickMin(const size_t x,const size_t y)
00523 {
00524 if (x < y)
00525 return(x);
00526 return(y);
00527 }
00528
00529 MagickExport MagickBooleanType DecipherImage(Image *image,
00530 const char *passphrase,ExceptionInfo *exception)
00531 {
00532 MagickBooleanType
00533 status;
00534
00535 StringInfo
00536 *passkey;
00537
00538 if (passphrase == (const char *) NULL)
00539 return(MagickTrue);
00540 passkey=StringToStringInfo(passphrase);
00541 if (passkey == (StringInfo *) NULL)
00542 return(MagickFalse);
00543 status=PasskeyDecipherImage(image,passkey,exception);
00544 passkey=DestroyStringInfo(passkey);
00545 return(status);
00546 }
00547
00548 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
00549 const StringInfo *passkey,ExceptionInfo *exception)
00550 {
00551 #define DecipherImageTag "Decipher/Image "
00552
00553 AESInfo
00554 *aes_info;
00555
00556 const unsigned char
00557 *digest;
00558
00559 IndexPacket
00560 *indexes;
00561
00562 long
00563 y;
00564
00565 MagickBooleanType
00566 proceed;
00567
00568 QuantumInfo
00569 *quantum_info;
00570
00571 QuantumType
00572 quantum_type;
00573
00574 SignatureInfo
00575 *signature_info;
00576
00577 register unsigned char
00578 *p;
00579
00580 size_t
00581 length;
00582
00583 StringInfo
00584 *key,
00585 *nonce;
00586
00587 unsigned char
00588 input_block[AESBlocksize],
00589 output_block[AESBlocksize],
00590 *pixels;
00591
00592 CacheView
00593 *image_view;
00594
00595
00596
00597
00598 assert(image != (Image *) NULL);
00599 assert(image->signature == MagickSignature);
00600 if (image->debug != MagickFalse)
00601 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00602 assert(exception != (ExceptionInfo *) NULL);
00603 assert(exception->signature == MagickSignature);
00604 if (passkey == (const StringInfo *) NULL)
00605 return(MagickTrue);
00606 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
00607 if (quantum_info == (QuantumInfo *) NULL)
00608 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00609 image->filename);
00610 aes_info=AcquireAESInfo();
00611 key=CloneStringInfo(passkey);
00612 if (key == (StringInfo *) NULL)
00613 {
00614 aes_info=DestroyAESInfo(aes_info);
00615 quantum_info=DestroyQuantumInfo(quantum_info);
00616 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00617 image->filename);
00618 }
00619 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
00620 if (nonce == (StringInfo *) NULL)
00621 {
00622 key=DestroyStringInfo(key);
00623 aes_info=DestroyAESInfo(aes_info);
00624 quantum_info=DestroyQuantumInfo(quantum_info);
00625 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00626 image->filename);
00627 }
00628 SetAESKey(aes_info,key);
00629 key=DestroyStringInfo(key);
00630 signature_info=AcquireSignatureInfo();
00631 UpdateSignature(signature_info,nonce);
00632 SetStringInfoLength(nonce,sizeof(quantum_info->extent));
00633 SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
00634 UpdateSignature(signature_info,nonce);
00635 FinalizeSignature(signature_info);
00636 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00637 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00638 (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
00639 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
00640 nonce=DestroyStringInfo(nonce);
00641 signature_info=DestroySignatureInfo(signature_info);
00642
00643
00644
00645 quantum_type=GetQuantumType(image,exception);
00646 pixels=GetQuantumPixels(quantum_info);
00647 image_view=AcquireCacheView(image);
00648 for (y=0; y < (long) image->rows; y++)
00649 {
00650 register long
00651 x;
00652
00653 register PixelPacket
00654 *__restrict q;
00655
00656 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
00657 if (q == (PixelPacket *) NULL)
00658 break;
00659 indexes=GetCacheViewAuthenticIndexQueue(image_view);
00660 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
00661 pixels,exception);
00662 p=pixels;
00663 for (x=0; x < (long) length; x++)
00664 {
00665 (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
00666 sizeof(*output_block));
00667 EncipherAESBlock(aes_info,output_block,output_block);
00668 (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
00669 sizeof(*input_block));
00670 input_block[AESBlocksize-1]=(*p);
00671 *p++^=(*output_block);
00672 }
00673 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
00674 pixels,exception);
00675 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
00676 break;
00677 proceed=SetImageProgress(image,DecipherImageTag,y,image->rows);
00678 if (proceed == MagickFalse)
00679 break;
00680 }
00681 image_view=DestroyCacheView(image_view);
00682 (void) DeleteImageProperty(image,"cipher:type");
00683 (void) DeleteImageProperty(image,"cipher:mode");
00684 (void) DeleteImageProperty(image,"cipher:nonce");
00685 image->taint=MagickFalse;
00686
00687
00688
00689 quantum_info=DestroyQuantumInfo(quantum_info);
00690 aes_info=DestroyAESInfo(aes_info);
00691 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00692 (void) ResetMagickMemory(output_block,0,sizeof(output_block));
00693 return(y == (long) image->rows ? MagickTrue : MagickFalse);
00694 }
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 MagickExport MagickBooleanType EncipherImage(Image *image,
00729 const char *passphrase,ExceptionInfo *exception)
00730 {
00731 MagickBooleanType
00732 status;
00733
00734 StringInfo
00735 *passkey;
00736
00737 if (passphrase == (const char *) NULL)
00738 return(MagickTrue);
00739 passkey=StringToStringInfo(passphrase);
00740 if (passkey == (StringInfo *) NULL)
00741 return(MagickFalse);
00742 status=PasskeyEncipherImage(image,passkey,exception);
00743 passkey=DestroyStringInfo(passkey);
00744 return(status);
00745 }
00746
00747 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
00748 const StringInfo *passkey,ExceptionInfo *exception)
00749 {
00750 #define EncipherImageTag "Encipher/Image "
00751
00752 AESInfo
00753 *aes_info;
00754
00755 char
00756 *signature;
00757
00758 const unsigned char
00759 *digest;
00760
00761 IndexPacket
00762 *indexes;
00763
00764 long
00765 y;
00766
00767 MagickBooleanType
00768 proceed;
00769
00770 QuantumInfo
00771 *quantum_info;
00772
00773 QuantumType
00774 quantum_type;
00775
00776 register unsigned char
00777 *p;
00778
00779 SignatureInfo
00780 *signature_info;
00781
00782 size_t
00783 length;
00784
00785 StringInfo
00786 *key,
00787 *nonce;
00788
00789 unsigned char
00790 input_block[AESBlocksize],
00791 output_block[AESBlocksize],
00792 *pixels;
00793
00794 CacheView
00795 *image_view;
00796
00797
00798
00799
00800 assert(image != (Image *) NULL);
00801 assert(image->signature == MagickSignature);
00802 if (image->debug != MagickFalse)
00803 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00804 assert(exception != (ExceptionInfo *) NULL);
00805 assert(exception->signature == MagickSignature);
00806 if (passkey == (const StringInfo *) NULL)
00807 return(MagickTrue);
00808 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
00809 return(MagickFalse);
00810 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
00811 if (quantum_info == (QuantumInfo *) NULL)
00812 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00813 image->filename);
00814 aes_info=AcquireAESInfo();
00815 key=CloneStringInfo(passkey);
00816 if (key == (StringInfo *) NULL)
00817 {
00818 aes_info=DestroyAESInfo(aes_info);
00819 quantum_info=DestroyQuantumInfo(quantum_info);
00820 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00821 image->filename);
00822 }
00823 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
00824 if (nonce == (StringInfo *) NULL)
00825 {
00826 key=DestroyStringInfo(key);
00827 aes_info=DestroyAESInfo(aes_info);
00828 quantum_info=DestroyQuantumInfo(quantum_info);
00829 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00830 image->filename);
00831 }
00832 SetAESKey(aes_info,key);
00833 key=DestroyStringInfo(key);
00834 signature_info=AcquireSignatureInfo();
00835 UpdateSignature(signature_info,nonce);
00836 SetStringInfoLength(nonce,sizeof(quantum_info->extent));
00837 SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
00838 UpdateSignature(signature_info,nonce);
00839 nonce=DestroyStringInfo(nonce);
00840 FinalizeSignature(signature_info);
00841 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00842 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00843 (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
00844 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
00845 signature=StringInfoToHexString(GetSignatureDigest(signature_info));
00846 (void) SetImageProperty(image,"cipher:type","AES");
00847 (void) SetImageProperty(image,"cipher:mode","CFB");
00848 (void) SetImageProperty(image,"cipher:nonce",signature);
00849 signature=DestroyString(signature);
00850 signature_info=DestroySignatureInfo(signature_info);
00851
00852
00853
00854 quantum_type=GetQuantumType(image,exception);
00855 pixels=GetQuantumPixels(quantum_info);
00856 image_view=AcquireCacheView(image);
00857 for (y=0; y < (long) image->rows; y++)
00858 {
00859 register long
00860 x;
00861
00862 register PixelPacket
00863 *__restrict q;
00864
00865 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
00866 if (q == (PixelPacket *) NULL)
00867 break;
00868 indexes=GetCacheViewAuthenticIndexQueue(image_view);
00869 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
00870 pixels,exception);
00871 p=pixels;
00872 for (x=0; x < (long) length; x++)
00873 {
00874 (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
00875 sizeof(*output_block));
00876 EncipherAESBlock(aes_info,output_block,output_block);
00877 *p^=(*output_block);
00878 (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
00879 sizeof(*input_block));
00880 input_block[AESBlocksize-1]=(*p++);
00881 }
00882 (void) ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
00883 pixels,exception);
00884 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
00885 break;
00886 proceed=SetImageProgress(image,EncipherImageTag,y,image->rows);
00887 if (proceed == MagickFalse)
00888 break;
00889 }
00890 image_view=DestroyCacheView(image_view);
00891 image->taint=MagickFalse;
00892
00893
00894
00895 quantum_info=DestroyQuantumInfo(quantum_info);
00896 aes_info=DestroyAESInfo(aes_info);
00897 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00898 (void) ResetMagickMemory(output_block,0,sizeof(output_block));
00899 return(y == (long) image->rows ? MagickTrue : MagickFalse);
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 static inline void InverseAddRoundKey(const unsigned int *alpha,
00930 unsigned int *beta)
00931 {
00932 register unsigned int
00933 i,
00934 j;
00935
00936 for (i=0; i < 4; i++)
00937 {
00938 beta[i]=0;
00939 for (j=0; j < 4; j++)
00940 beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
00941 ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
00942 ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
00943 ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
00944 }
00945 }
00946
00947 static inline unsigned int XTime(unsigned char alpha)
00948 {
00949 unsigned char
00950 beta;
00951
00952 beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
00953 alpha<<=1;
00954 alpha^=beta;
00955 return(alpha);
00956 }
00957
00958 static inline unsigned int RotateRight(const unsigned int x)
00959 {
00960 return((x >> 8) | ((x & 0xff) << 24));
00961 }
00962
00963 static void SetAESKey(AESInfo *aes_info,const StringInfo *key)
00964 {
00965 long
00966 bytes,
00967 n;
00968
00969 register long
00970 i;
00971
00972 unsigned char
00973 *datum;
00974
00975 unsigned int
00976 alpha,
00977 beta;
00978
00979
00980
00981
00982 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00983 assert(aes_info != (AESInfo *) NULL);
00984 assert(aes_info->signature == MagickSignature);
00985 assert(key != (StringInfo *) NULL);
00986 n=4;
00987 aes_info->rounds=10;
00988 if ((8*GetStringInfoLength(key)) >= 256)
00989 {
00990 n=8;
00991 aes_info->rounds=14;
00992 }
00993 else
00994 if ((8*GetStringInfoLength(key)) >= 192)
00995 {
00996 n=6;
00997 aes_info->rounds=12;
00998 }
00999
01000
01001
01002 datum=GetStringInfoDatum(aes_info->key);
01003 (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
01004 (void) CopyMagickMemory(datum,GetStringInfoDatum(key),MagickMin(
01005 GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
01006 for (i=0; i < n; i++)
01007 aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) |
01008 (datum[4*i+2] << 16) | (datum[4*i+3] << 24);
01009 beta=1;
01010 bytes=(AESBlocksize/4)*(aes_info->rounds+1);
01011 for (i=n; i < bytes; i++)
01012 {
01013 alpha=aes_info->encipher_key[i-1];
01014 if ((i % n) == 0)
01015 {
01016 alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
01017 beta=XTime((unsigned char) (beta & 0xff));
01018 }
01019 else
01020 if ((n > 6) && ((i % n) == 4))
01021 alpha=ByteSubTransform(alpha,SBox);
01022 aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
01023 }
01024
01025
01026
01027 for (i=0; i < 4; i++)
01028 {
01029 aes_info->decipher_key[i]=aes_info->encipher_key[i];
01030 aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
01031 }
01032 for (i=4; i < (bytes-4); i+=4)
01033 InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
01034
01035
01036
01037 datum=GetStringInfoDatum(aes_info->key);
01038 (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
01039 alpha=0;
01040 beta=0;
01041 }
01042 #else
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 MagickExport MagickBooleanType DecipherImage(Image *image,
01077 const char *passphrase,ExceptionInfo *exception)
01078 {
01079 assert(image != (Image *) NULL);
01080 assert(image->signature == MagickSignature);
01081 if (image->debug != MagickFalse)
01082 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01083 assert(exception != (ExceptionInfo *) NULL);
01084 assert(exception->signature == MagickSignature);
01085 (void) passphrase;
01086 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01087 }
01088
01089 MagickExport MagickBooleanType PasskeyDecipherImage(Image *image,
01090 const StringInfo *passkey,ExceptionInfo *exception)
01091 {
01092 assert(image != (Image *) NULL);
01093 assert(image->signature == MagickSignature);
01094 if (image->debug != MagickFalse)
01095 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01096 assert(exception != (ExceptionInfo *) NULL);
01097 assert(exception->signature == MagickSignature);
01098 (void) passkey;
01099 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01100 }
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 MagickExport MagickBooleanType EncipherImage(Image *image,
01133 const char *passphrase,ExceptionInfo *exception)
01134 {
01135 assert(image != (Image *) NULL);
01136 assert(image->signature == MagickSignature);
01137 if (image->debug != MagickFalse)
01138 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01139 assert(exception != (ExceptionInfo *) NULL);
01140 assert(exception->signature == MagickSignature);
01141 (void) passphrase;
01142 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01143 }
01144
01145 MagickExport MagickBooleanType PasskeyEncipherImage(Image *image,
01146 const StringInfo *passkey,ExceptionInfo *exception)
01147 {
01148 assert(image != (Image *) NULL);
01149 assert(image->signature == MagickSignature);
01150 if (image->debug != MagickFalse)
01151 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01152 assert(exception != (ExceptionInfo *) NULL);
01153 assert(exception->signature == MagickSignature);
01154 (void) passkey;
01155 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01156 }
01157 #endif