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
00235
00236
00237
00238
00239
00240 static inline size_t MagickMin(const size_t x,const size_t y)
00241 {
00242 if (x < y)
00243 return(x);
00244 return(y);
00245 }
00246
00247 MagickExport MagickBooleanType DecipherImage(Image *image,
00248 const char *passphrase,ExceptionInfo *exception)
00249 {
00250 #define DecipherImageTag "Decipher/Image "
00251
00252 AESInfo
00253 *aes_info;
00254
00255 const unsigned char
00256 *digest;
00257
00258 IndexPacket
00259 *indexes;
00260
00261 long
00262 y;
00263
00264 MagickBooleanType
00265 proceed;
00266
00267 QuantumInfo
00268 *quantum_info;
00269
00270 QuantumType
00271 quantum_type;
00272
00273 register long
00274 x;
00275
00276 register PixelPacket
00277 *q;
00278
00279 register unsigned char
00280 *p;
00281
00282 SignatureInfo
00283 *signature_info;
00284
00285 size_t
00286 length;
00287
00288 StringInfo
00289 *key,
00290 *nonce;
00291
00292 unsigned char
00293 input_block[AESBlocksize],
00294 output_block[AESBlocksize],
00295 *pixels;
00296
00297
00298
00299
00300 assert(image != (Image *) NULL);
00301 assert(image->signature == MagickSignature);
00302 if (image->debug != MagickFalse)
00303 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00304 assert(exception != (ExceptionInfo *) NULL);
00305 assert(exception->signature == MagickSignature);
00306 if (passphrase == (const char *) NULL)
00307 return(MagickTrue);
00308 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
00309 if (quantum_info == (QuantumInfo *) NULL)
00310 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00311 image->filename);
00312 aes_info=AcquireAESInfo();
00313 key=StringToStringInfo(passphrase);
00314 if (key == (StringInfo *) NULL)
00315 {
00316 aes_info=DestroyAESInfo(aes_info);
00317 quantum_info=DestroyQuantumInfo(quantum_info);
00318 return(MagickFalse);
00319 }
00320 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
00321 if (nonce == (StringInfo *) NULL)
00322 {
00323 key=DestroyStringInfo(key);
00324 aes_info=DestroyAESInfo(aes_info);
00325 quantum_info=DestroyQuantumInfo(quantum_info);
00326 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00327 image->filename);
00328 }
00329 SetAESKey(aes_info,key);
00330 key=DestroyStringInfo(key);
00331 signature_info=AcquireSignatureInfo();
00332 UpdateSignature(signature_info,nonce);
00333 SetStringInfoLength(nonce,sizeof(quantum_info->extent));
00334 SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
00335 UpdateSignature(signature_info,nonce);
00336 FinalizeSignature(signature_info);
00337 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00338 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00339 (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
00340 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
00341 nonce=DestroyStringInfo(nonce);
00342 signature_info=DestroySignatureInfo(signature_info);
00343
00344
00345
00346 quantum_type=GetQuantumType(image,exception);
00347 pixels=GetQuantumPixels(quantum_info);
00348 for (y=0; y < (long) image->rows; y++)
00349 {
00350 q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
00351 if (q == (PixelPacket *) NULL)
00352 break;
00353 indexes=GetAuthenticIndexQueue(image);
00354 length=ExportQuantumPixels(image,(const ViewInfo *) NULL,quantum_info,
00355 quantum_type,pixels,exception);
00356 p=pixels;
00357 for (x=0; x < (long) length; x++)
00358 {
00359 (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
00360 sizeof(*output_block));
00361 EncipherAESBlock(aes_info,output_block,output_block);
00362 (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
00363 sizeof(*input_block));
00364 input_block[AESBlocksize-1]=(*p);
00365 *p++^=(*output_block);
00366 }
00367 (void) ImportQuantumPixels(image,(ViewInfo *) NULL,quantum_info,
00368 quantum_type,pixels,exception);
00369 if (SyncAuthenticPixels(image,exception) == MagickFalse)
00370 break;
00371 proceed=SetImageProgress(image,DecipherImageTag,y,image->rows);
00372 if (proceed == MagickFalse)
00373 break;
00374 }
00375 (void) DeleteImageProperty(image,"cipher:type");
00376 (void) DeleteImageProperty(image,"cipher:mode");
00377 (void) DeleteImageProperty(image,"cipher:nonce");
00378 image->taint=MagickFalse;
00379
00380
00381
00382 quantum_info=DestroyQuantumInfo(quantum_info);
00383 aes_info=DestroyAESInfo(aes_info);
00384 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00385 (void) ResetMagickMemory(output_block,0,sizeof(output_block));
00386 return(y == (long) image->rows ? MagickTrue : MagickFalse);
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 static AESInfo *DestroyAESInfo(AESInfo *aes_info)
00412 {
00413 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00414 assert(aes_info != (AESInfo *) NULL);
00415 assert(aes_info->signature == MagickSignature);
00416 if (aes_info->decipher_key != (unsigned int *) NULL)
00417 aes_info->decipher_key=(unsigned int *) RelinquishMagickMemory(
00418 aes_info->decipher_key);
00419 if (aes_info->encipher_key != (unsigned int *) NULL)
00420 aes_info->encipher_key=(unsigned int *) RelinquishMagickMemory(
00421 aes_info->encipher_key);
00422 if (aes_info->key != (StringInfo *) NULL)
00423 aes_info->key=DestroyStringInfo(aes_info->key);
00424 aes_info->signature=(~MagickSignature);
00425 aes_info=(AESInfo *) RelinquishMagickMemory(aes_info);
00426 return(aes_info);
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 MagickExport MagickBooleanType EncipherImage(Image *image,
00457 const char *passphrase,ExceptionInfo *exception)
00458 {
00459 #define EncipherImageTag "Encipher/Image "
00460
00461 AESInfo
00462 *aes_info;
00463
00464 char
00465 *signature;
00466
00467 const unsigned char
00468 *digest;
00469
00470 IndexPacket
00471 *indexes;
00472
00473 long
00474 y;
00475
00476 MagickBooleanType
00477 proceed;
00478
00479 QuantumInfo
00480 *quantum_info;
00481
00482 QuantumType
00483 quantum_type;
00484
00485 register long
00486 x;
00487
00488 register PixelPacket
00489 *q;
00490
00491 register unsigned char
00492 *p;
00493
00494 SignatureInfo
00495 *signature_info;
00496
00497 size_t
00498 length;
00499
00500 StringInfo
00501 *key,
00502 *nonce;
00503
00504 unsigned char
00505 input_block[AESBlocksize],
00506 output_block[AESBlocksize],
00507 *pixels;
00508
00509
00510
00511
00512 assert(image != (Image *) NULL);
00513 assert(image->signature == MagickSignature);
00514 if (image->debug != MagickFalse)
00515 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00516 assert(exception != (ExceptionInfo *) NULL);
00517 assert(exception->signature == MagickSignature);
00518 if (passphrase == (const char *) NULL)
00519 return(MagickTrue);
00520 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
00521 return(MagickFalse);
00522 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
00523 if (quantum_info == (QuantumInfo *) NULL)
00524 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00525 image->filename);
00526 aes_info=AcquireAESInfo();
00527 key=StringToStringInfo(passphrase);
00528 if (key == (StringInfo *) NULL)
00529 {
00530 aes_info=DestroyAESInfo(aes_info);
00531 quantum_info=DestroyQuantumInfo(quantum_info);
00532 return(MagickFalse);
00533 }
00534 nonce=SplitStringInfo(key,GetStringInfoLength(key)/2);
00535 if (nonce == (StringInfo *) NULL)
00536 {
00537 key=DestroyStringInfo(key);
00538 aes_info=DestroyAESInfo(aes_info);
00539 quantum_info=DestroyQuantumInfo(quantum_info);
00540 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00541 image->filename);
00542 }
00543 SetAESKey(aes_info,key);
00544 key=DestroyStringInfo(key);
00545 signature_info=AcquireSignatureInfo();
00546 UpdateSignature(signature_info,nonce);
00547 SetStringInfoLength(nonce,sizeof(quantum_info->extent));
00548 SetStringInfoDatum(nonce,(const unsigned char *) &quantum_info->extent);
00549 UpdateSignature(signature_info,nonce);
00550 nonce=DestroyStringInfo(nonce);
00551 FinalizeSignature(signature_info);
00552 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00553 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00554 (void) CopyMagickMemory(input_block,digest,MagickMin(AESBlocksize,
00555 GetSignatureDigestsize(signature_info))*sizeof(*input_block));
00556 signature=StringInfoToHexString(GetSignatureDigest(signature_info));
00557 (void) SetImageProperty(image,"cipher:type","AES");
00558 (void) SetImageProperty(image,"cipher:mode","CFB");
00559 (void) SetImageProperty(image,"cipher:nonce",signature);
00560 signature=DestroyString(signature);
00561 signature_info=DestroySignatureInfo(signature_info);
00562
00563
00564
00565 quantum_type=GetQuantumType(image,exception);
00566 pixels=GetQuantumPixels(quantum_info);
00567 for (y=0; y < (long) image->rows; y++)
00568 {
00569 q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
00570 if (q == (PixelPacket *) NULL)
00571 break;
00572 indexes=GetAuthenticIndexQueue(image);
00573 length=ExportQuantumPixels(image,(const ViewInfo *) NULL,quantum_info,
00574 quantum_type,pixels,exception);
00575 p=pixels;
00576 for (x=0; x < (long) length; x++)
00577 {
00578 (void) CopyMagickMemory(output_block,input_block,AESBlocksize*
00579 sizeof(*output_block));
00580 EncipherAESBlock(aes_info,output_block,output_block);
00581 *p^=(*output_block);
00582 (void) CopyMagickMemory(input_block,input_block+1,(AESBlocksize-1)*
00583 sizeof(*input_block));
00584 input_block[AESBlocksize-1]=(*p++);
00585 }
00586 (void) ImportQuantumPixels(image,(ViewInfo *) NULL,quantum_info,
00587 quantum_type,pixels,exception);
00588 if (SyncAuthenticPixels(image,exception) == MagickFalse)
00589 break;
00590 proceed=SetImageProgress(image,EncipherImageTag,y,image->rows);
00591 if (proceed == MagickFalse)
00592 break;
00593 }
00594 image->taint=MagickFalse;
00595
00596
00597
00598 quantum_info=DestroyQuantumInfo(quantum_info);
00599 aes_info=DestroyAESInfo(aes_info);
00600 (void) ResetMagickMemory(input_block,0,sizeof(input_block));
00601 (void) ResetMagickMemory(output_block,0,sizeof(output_block));
00602 return(y == (long) image->rows ? MagickTrue : MagickFalse);
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 static inline void AddRoundKey(const unsigned int *ciphertext,
00635 const unsigned int *key,unsigned int *plaintext)
00636 {
00637 register long
00638 i;
00639
00640
00641
00642
00643 for (i=0; i < 4; i++)
00644 plaintext[i]=key[i] ^ ciphertext[i];
00645 }
00646
00647 static inline unsigned char ByteMultiply(const unsigned char alpha,
00648 const unsigned char beta)
00649 {
00650
00651
00652
00653 if ((alpha == 0) || (beta == 0))
00654 return(0);
00655 return(InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
00656 }
00657
00658 static inline unsigned int ByteSubTransform(unsigned int x,
00659 unsigned char *s_box)
00660 {
00661 unsigned int
00662 key;
00663
00664
00665
00666
00667 key=(s_box[x & 0xff]) | (s_box[(x >> 8) & 0xff] << 8) |
00668 (s_box[(x >> 16) & 0xff] << 16) | (s_box[(x >> 24) & 0xff] << 24);
00669 return(key);
00670 }
00671
00672 static void FinalizeRoundKey(const unsigned int *ciphertext,
00673 const unsigned int *key,unsigned char *plaintext)
00674 {
00675 register unsigned char
00676 *p;
00677
00678 register unsigned int
00679 i,
00680 j;
00681
00682 unsigned int
00683 value;
00684
00685
00686
00687
00688 p=plaintext;
00689 for (i=0; i < 4; i++)
00690 {
00691 value=ciphertext[i] ^ key[i];
00692 for (j=0; j < 4; j++)
00693 *p++=(value >> (8*j)) & 0xff;
00694 }
00695
00696
00697
00698 value=0;
00699 }
00700
00701 static void InitializeRoundKey(const unsigned char *ciphertext,
00702 const unsigned int *key,unsigned int *plaintext)
00703 {
00704 register const unsigned char
00705 *p;
00706
00707 register unsigned int
00708 i,
00709 j;
00710
00711 unsigned int
00712 value;
00713
00714 p=ciphertext;
00715 for (i=0; i < 4; i++)
00716 {
00717 value=0;
00718 for (j=0; j < 4; j++)
00719 value|=(*p++ << (8*j));
00720 plaintext[i]=key[i] ^ value;
00721 }
00722
00723
00724
00725 value=0;
00726 }
00727
00728 static inline unsigned int RotateLeft(const unsigned int x)
00729 {
00730 return(((x << 8) | ((x >> 24) & 0xff)));
00731 }
00732
00733 static void EncipherAESBlock(AESInfo *aes_info,const unsigned char *plaintext,
00734 unsigned char *ciphertext)
00735 {
00736 register long
00737 i,
00738 j;
00739
00740 static int
00741 map[4][4] =
00742 {
00743 { 0, 1, 2, 3 },
00744 { 1, 2, 3, 0 },
00745 { 2, 3, 0, 1 },
00746 { 3, 0, 1, 2 }
00747 };
00748
00749 static unsigned int
00750 D[] =
00751 {
00752 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
00753 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
00754 0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
00755 0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
00756 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
00757 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
00758 0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
00759 0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
00760 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
00761 0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
00762 0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
00763 0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
00764 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
00765 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
00766 0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
00767 0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
00768 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
00769 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
00770 0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
00771 0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
00772 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
00773 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
00774 0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
00775 0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
00776 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
00777 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
00778 0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
00779 0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
00780 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
00781 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
00782 0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
00783 0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
00784 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
00785 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
00786 0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
00787 0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
00788 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
00789 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
00790 0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
00791 0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
00792 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
00793 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
00794 0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
00795 0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
00796 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
00797 0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
00798 0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
00799 0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
00800 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
00801 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
00802 0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
00803 0x3a16162cU
00804 };
00805
00806 unsigned int
00807 alpha,
00808 key[4],
00809 text[4];
00810
00811
00812
00813
00814 (void) memset(text,0,sizeof(text));
00815 InitializeRoundKey(plaintext,aes_info->encipher_key,text);
00816 for (i=1; i < aes_info->rounds; i++)
00817 {
00818
00819
00820
00821 for (j=0; j < 4; j++)
00822 key[j]=D[text[j] & 0xff] ^
00823 RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
00824 RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
00825 RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
00826 AddRoundKey(key,aes_info->encipher_key+4*i,text);
00827 }
00828 for (i=0; i < 4; i++)
00829 {
00830 alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
00831 ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
00832 key[i]=ByteSubTransform(alpha,SBox);
00833 }
00834 FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
00835
00836
00837
00838 alpha=0;
00839 (void) ResetMagickMemory(key,0,sizeof(key));
00840 (void) ResetMagickMemory(text,0,sizeof(text));
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 static inline void InverseAddRoundKey(const unsigned int *alpha,
00871 unsigned int *beta)
00872 {
00873 register unsigned int
00874 i,
00875 j;
00876
00877 for (i=0; i < 4; i++)
00878 {
00879 beta[i]=0;
00880 for (j=0; j < 4; j++)
00881 beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
00882 ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
00883 ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
00884 ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
00885 }
00886 }
00887
00888 static inline unsigned int XTime(unsigned char alpha)
00889 {
00890 unsigned char
00891 beta;
00892
00893 beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
00894 alpha<<=1;
00895 alpha^=beta;
00896 return(alpha);
00897 }
00898
00899 static inline unsigned int RotateRight(const unsigned int x)
00900 {
00901 return((x >> 8) | ((x & 0xff) << 24));
00902 }
00903
00904 static void SetAESKey(AESInfo *aes_info,const StringInfo *key)
00905 {
00906 long
00907 bytes,
00908 n;
00909
00910 register long
00911 i;
00912
00913 unsigned char
00914 *datum;
00915
00916 unsigned int
00917 alpha,
00918 beta;
00919
00920
00921
00922
00923 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00924 assert(aes_info != (AESInfo *) NULL);
00925 assert(aes_info->signature == MagickSignature);
00926 assert(key != (StringInfo *) NULL);
00927 n=4;
00928 aes_info->rounds=10;
00929 if ((8*GetStringInfoLength(key)) >= 256)
00930 {
00931 n=8;
00932 aes_info->rounds=14;
00933 }
00934 else
00935 if ((8*GetStringInfoLength(key)) >= 192)
00936 {
00937 n=6;
00938 aes_info->rounds=12;
00939 }
00940
00941
00942
00943 datum=GetStringInfoDatum(aes_info->key);
00944 (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
00945 (void) CopyMagickMemory(datum,GetStringInfoDatum(key),MagickMin(
00946 GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
00947 for (i=0; i < n; i++)
00948 aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) |
00949 (datum[4*i+2] << 16) | (datum[4*i+3] << 24);
00950 beta=1;
00951 bytes=(AESBlocksize/4)*(aes_info->rounds+1);
00952 for (i=n; i < bytes; i++)
00953 {
00954 alpha=aes_info->encipher_key[i-1];
00955 if ((i % n) == 0)
00956 {
00957 alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
00958 beta=XTime((unsigned char) (beta & 0xff));
00959 }
00960 else
00961 if ((n > 6) && ((i % n) == 4))
00962 alpha=ByteSubTransform(alpha,SBox);
00963 aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
00964 }
00965
00966
00967
00968 for (i=0; i < 4; i++)
00969 {
00970 aes_info->decipher_key[i]=aes_info->encipher_key[i];
00971 aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
00972 }
00973 for (i=4; i < (bytes-4); i+=4)
00974 InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
00975
00976
00977
00978 datum=GetStringInfoDatum(aes_info->key);
00979 (void) ResetMagickMemory(datum,0,GetStringInfoLength(aes_info->key));
00980 alpha=0;
00981 beta=0;
00982 }
00983 #else
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012 MagickExport MagickBooleanType DecipherImage(Image *image,
01013 const char *passphrase,ExceptionInfo *exception)
01014 {
01015 assert(image != (Image *) NULL);
01016 assert(image->signature == MagickSignature);
01017 if (image->debug != MagickFalse)
01018 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01019 assert(exception != (ExceptionInfo *) NULL);
01020 assert(exception->signature == MagickSignature);
01021 (void) passphrase;
01022 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 MagickExport MagickBooleanType EncipherImage(Image *image,
01053 const char *passphrase,ExceptionInfo *exception)
01054 {
01055 assert(image != (Image *) NULL);
01056 assert(image->signature == MagickSignature);
01057 if (image->debug != MagickFalse)
01058 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01059 assert(exception != (ExceptionInfo *) NULL);
01060 assert(exception->signature == MagickSignature);
01061 (void) passphrase;
01062 ThrowBinaryException(ImageError,"CipherSupportNotEnabled",image->filename);
01063 }
01064 #endif