WizardsToolkit  1.0.7
cipher.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                   CCCC  IIIII  PPPP   H   H  EEEEE  RRRR                    %
00006 %                  C        I    P   P  H   H  E      R   R                   %
00007 %                  C        I    PPPP   HHHHH  EEE    RRRR                    %
00008 %                  C        I    P      H   H  E      R R                     %
00009 %                   CCCC  IIIII  P      H   H  EEEEE  R  R                    %
00010 %                                                                             %
00011 %                                                                             %
00012 %              Wizard's Toolkit Secure Cipher Algorithm Methods               %
00013 %                                                                             %
00014 %                             Software Design                                 %
00015 %                               John Cristy                                   %
00016 %                               March  2003                                   %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.wizards-toolkit.org/script/license.php                        %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 % See http://csrc.nist.gov/cryptval/shs.htm.
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "wizard/studio.h"
00043 #include "wizard/aes.h"
00044 #include "wizard/cipher.h"
00045 #include "wizard/exception.h"
00046 #include "wizard/exception-private.h"
00047 #include "wizard/memory_.h"
00048 #include "wizard/random_.h"
00049 #include "wizard/serpent.h"
00050 #include "wizard/twofish.h"
00051 
00052 /*
00053   Define declarations.
00054 */
00055 #define CipherRandomHash  SHA256Hash
00056 
00057 /*
00058   Typedef declarations.
00059 */
00060 typedef void
00061   (*DecipherBlock)(void *,const unsigned char *,const unsigned char *),
00062   (*EncipherBlock)(void *,const unsigned char *,const unsigned char *);
00063 
00064 struct _CipherInfo
00065 {
00066   void
00067     *handle;
00068 
00069   CipherType
00070     cipher;
00071 
00072   CipherMode
00073     mode;
00074 
00075   size_t
00076     blocksize;
00077 
00078   DecipherBlock
00079     decipher_block;
00080 
00081   DecipherBlock
00082     encipher_block;
00083 
00084   StringInfo
00085     *nonce;
00086 
00087   RandomInfo
00088     *random_info;
00089 
00090   time_t
00091     timestamp;
00092 
00093   size_t
00094     signature;
00095 };
00096 
00097 /*
00098   Forward declaration.
00099 */
00100 static StringInfo
00101   *DecipherCTRMode(CipherInfo *,StringInfo *),
00102   *DecipherECBMode(CipherInfo *,StringInfo *),
00103   *DecipherOFBMode(CipherInfo *,StringInfo *),
00104   *EncipherCTRMode(CipherInfo *,StringInfo *),
00105   *EncipherECBMode(CipherInfo *,StringInfo *),
00106   *EncipherOFBMode(CipherInfo *,StringInfo *);
00107 
00108 /*
00109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00110 %                                                                             %
00111 %                                                                             %
00112 %                                                                             %
00113 %   A c q u i r e C i p h e r I n f o                                         %
00114 %                                                                             %
00115 %                                                                             %
00116 %                                                                             %
00117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00118 %
00119 %  AcquireCipherInfo() allocates the CipherInfo structure.
00120 %
00121 %  The format of the AcquireCipherInfo method is:
00122 %
00123 %      CipherInfo *AcquireCipherInfo(const CipherType cipher,
00124 %        const CipherMode mode)
00125 %
00126 %  A description of each parameter follows:
00127 %
00128 %    o cipher: The cipher type.
00129 %
00130 %    o mode: The cipher mode.
00131 %
00132 */
00133 WizardExport CipherInfo *AcquireCipherInfo(const CipherType cipher,
00134   const CipherMode mode)
00135 {
00136   CipherInfo
00137     *cipher_info;
00138 
00139   cipher_info=(CipherInfo *) AcquireWizardMemory(sizeof(*cipher_info));
00140   if (cipher_info == (CipherInfo *) NULL)
00141     ThrowWizardFatalError(CipherDomain,MemoryError);
00142   (void) ResetWizardMemory(cipher_info,0,sizeof(*cipher_info));
00143   cipher_info->cipher=cipher;
00144   switch (cipher_info->cipher)
00145   {
00146     case AESCipher:
00147     {
00148       AESInfo
00149         *aes_info;
00150 
00151       aes_info=AcquireAESInfo();
00152       cipher_info->handle=(CipherInfo *) aes_info;
00153       cipher_info->blocksize=GetAESBlocksize(aes_info);
00154       cipher_info->decipher_block=(DecipherBlock) DecipherAESBlock;
00155       cipher_info->encipher_block=(DecipherBlock) EncipherAESBlock;
00156       break;
00157     }
00158     case SerpentCipher:
00159     {
00160       SerpentInfo
00161         *serpent_info;
00162 
00163       serpent_info=AcquireSerpentInfo();
00164       cipher_info->handle=(CipherInfo *) serpent_info;
00165       cipher_info->blocksize=GetSerpentBlocksize(serpent_info);
00166       cipher_info->decipher_block=(DecipherBlock) DecipherSerpentBlock;
00167       cipher_info->encipher_block=(DecipherBlock) EncipherSerpentBlock;
00168       break;
00169     }
00170     case TwofishCipher:
00171     {
00172       TwofishInfo
00173         *twofish_info;
00174 
00175       twofish_info=AcquireTwofishInfo();
00176       cipher_info->handle=(CipherInfo *) twofish_info;
00177       cipher_info->blocksize=GetTwofishBlocksize(twofish_info);
00178       cipher_info->decipher_block=(DecipherBlock) DecipherTwofishBlock;
00179       cipher_info->encipher_block=(DecipherBlock) EncipherTwofishBlock;
00180       break;
00181     }
00182     default:
00183       ThrowWizardFatalError(CipherDomain,EnumerateError);
00184   }
00185   cipher_info->mode=mode;
00186   if (cipher_info->nonce != (StringInfo *) NULL)
00187     cipher_info->nonce=DestroyStringInfo(cipher_info->nonce);
00188   cipher_info->random_info=AcquireRandomInfo(CipherRandomHash);
00189   cipher_info->timestamp=time((time_t *) NULL);
00190   cipher_info->signature=WizardSignature;
00191   cipher_info->nonce=GenerateCipherNonce(cipher_info);
00192   return(cipher_info);
00193 }
00194 
00195 /*
00196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00197 %                                                                             %
00198 %                                                                             %
00199 %                                                                             %
00200 +   D e c i p h e r C B C M o d e                                             %
00201 %                                                                             %
00202 %                                                                             %
00203 %                                                                             %
00204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00205 %
00206 %  DecipherCBCMode() deciphers with the cipher in Cipher Block Chaining mode.
00207 %  This mode is a confidentiality mode whose enciphering process features the
00208 %  combining ("chaining") of the plaintext blocks with the previous ciphertext
00209 %  blocks.  The CBC mode requires an IV to combine with the first plaintext
00210 %  block. The IV need not be secret, but it must be unpredictable.
00211 %
00212 %  The format of the DecipherCBCMode method is:
00213 %
00214 %     StringInfo *DecipherCBCMode(CipherInfo *cipher_info,
00215 %       StringInfo *ciphertext)
00216 %
00217 %  A description of each parameter follows:
00218 %
00219 %    o cipher_info: The cipher context.
00220 %
00221 %    o ciphertext: The cipher text.
00222 %
00223 */
00224 static StringInfo *DecipherCBCMode(CipherInfo *cipher_info,
00225   StringInfo *ciphertext)
00226 {
00227   register size_t
00228     i;
00229 
00230   register unsigned char
00231     *p,
00232     *q;
00233 
00234   size_t
00235     blocksize;
00236 
00237   StringInfo
00238     *plaintext;
00239 
00240   unsigned char
00241     input_block[MaxCipherBlocksize],
00242     output_block[MaxCipherBlocksize];
00243 
00244   /*
00245     Decipher in CBC mode.
00246   */
00247   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00248   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00249   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00250   blocksize=cipher_info->blocksize;
00251   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
00252   WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
00253   plaintext=ciphertext;
00254   p=GetStringInfoDatum(cipher_info->nonce);
00255   for (i=0; i < blocksize; i++)
00256     input_block[i]=p[i];
00257   q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
00258   for (p=GetStringInfoDatum(ciphertext); p < q; p+=blocksize)
00259   {
00260     for (i=0; i < blocksize; i++)
00261       output_block[i]=p[i];
00262     cipher_info->decipher_block(cipher_info->handle,p,p);
00263     for (i=0; i < blocksize; i++)
00264       p[i]^=input_block[i];
00265     for (i=0; i < blocksize; i++)
00266       input_block[i]=output_block[i];
00267   }
00268   /*
00269     Reset registers.
00270   */
00271   (void) ResetWizardMemory(input_block,0,sizeof(input_block));
00272   (void) ResetWizardMemory(output_block,0,sizeof(output_block));
00273   return(plaintext);
00274 }
00275 
00276 /*
00277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00278 %                                                                             %
00279 %                                                                             %
00280 %                                                                             %
00281 +   D e c i p h e r C F B M o d e                                             %
00282 %                                                                             %
00283 %                                                                             %
00284 %                                                                             %
00285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00286 %
00287 %  DecipherCFBMode() deciphers with the cipher in Cipher Feedback mode. This
00288 %  mode is a confidentiality mode that features the feedback of successive
00289 %  ciphertext segments into the input blocks of the forward cipher to generate
00290 %  output blocks that are exclusive-ORed with the plaintext to produce the
00291 %  ciphertext, and vice versa. The CFB mode requires an IV as the initial
00292 %  input block. The IV need not be secret, but it must be unpredictable.
00293 %
00294 %  The format of the DecipherCFBMode method is:
00295 %
00296 %     StringInfo *DecipherCFBMode(CipherInfo *cipher_info,
00297 %       StringInfo *ciphertext)
00298 %
00299 %  A description of each parameter follows:
00300 %
00301 %    o cipher_info: The cipher context.
00302 %
00303 %    o ciphertext: The cipher text.
00304 %
00305 */
00306 static StringInfo *DecipherCFBMode(CipherInfo *cipher_info,
00307   StringInfo *ciphertext)
00308 {
00309   register size_t
00310     i;
00311 
00312   register unsigned char
00313     *p,
00314     *q;
00315 
00316   size_t
00317     blocksize;
00318 
00319   StringInfo
00320     *plaintext;
00321 
00322   unsigned char
00323     input_block[MaxCipherBlocksize],
00324     output_block[MaxCipherBlocksize];
00325 
00326   /*
00327     Decipher in CFB mode.
00328   */
00329   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00330   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00331   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00332   blocksize=cipher_info->blocksize;
00333   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
00334   WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
00335   plaintext=ciphertext;
00336   p=GetStringInfoDatum(cipher_info->nonce);
00337   for (i=0; i < blocksize; i++)
00338     input_block[i]=p[i];
00339   q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
00340   for (p=GetStringInfoDatum(ciphertext); p < q; p++)
00341   {
00342     for (i=0; i < blocksize; i++)
00343       output_block[i]=input_block[i];
00344     cipher_info->encipher_block(cipher_info->handle,output_block,output_block);
00345     for (i=0; i < (blocksize-1); i++)
00346       input_block[i]=input_block[i+1];
00347     input_block[blocksize-1]=(*p);
00348     *p^=(*output_block);
00349   }
00350   /*
00351     Reset registers.
00352   */
00353   (void) ResetWizardMemory(input_block,0,sizeof(input_block));
00354   (void) ResetWizardMemory(output_block,0,sizeof(output_block));
00355   return(plaintext);
00356 }
00357 
00358 /*
00359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00360 %                                                                             %
00361 %                                                                             %
00362 %                                                                             %
00363 %   D e c i p h e r C i p h e r                                               %
00364 %                                                                             %
00365 %                                                                             %
00366 %                                                                             %
00367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00368 %
00369 %  DecipherCipher() deciphers ciphertext and returns plaintext. The deciphering
00370 %  is performed in-place and DecipherCipher() returns a pointer to the
00371 %  ciphertext string.
00372 %
00373 %  The format of the DecipherCipher method is:
00374 %
00375 %     StringInfo *DecipherCipher(CipherInfo *cipher_info,StringInfo *ciphertext)
00376 %
00377 %  A description of each parameter follows:
00378 %
00379 %    o cipher_info: The cipher context.
00380 %
00381 %    o ciphertext: The cipher text.
00382 %
00383 */
00384 
00385 WizardExport StringInfo *DecryptCipher(CipherInfo *cipher_info,
00386   StringInfo *plaintext)
00387 {
00388   return(DecipherCipher(cipher_info,plaintext));
00389 }
00390 
00391 WizardExport StringInfo *DecipherCipher(CipherInfo *cipher_info,
00392   StringInfo *ciphertext)
00393 {
00394   StringInfo
00395     *plaintext;
00396 
00397   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00398   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00399   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00400   WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
00401   plaintext=(StringInfo *) NULL;
00402   switch (cipher_info->mode)
00403   {
00404     case CBCMode:
00405     {
00406       plaintext=DecipherCBCMode(cipher_info,ciphertext);
00407       break;
00408     }
00409     case CFBMode:
00410     {
00411       plaintext=DecipherCFBMode(cipher_info,ciphertext);
00412       break;
00413     }
00414     case CTRMode:
00415     {
00416       plaintext=DecipherCTRMode(cipher_info,ciphertext);
00417       break;
00418     }
00419     case ECBMode:
00420     {
00421       plaintext=DecipherECBMode(cipher_info,ciphertext);
00422       break;
00423     }
00424     case OFBMode:
00425     {
00426       plaintext=DecipherOFBMode(cipher_info,ciphertext);
00427       break;
00428     }
00429     default:
00430       ThrowWizardFatalError(CipherDomain,EnumerateError);
00431   }
00432   return(plaintext);
00433 }
00434 
00435 /*
00436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00437 %                                                                             %
00438 %                                                                             %
00439 %                                                                             %
00440 +   D e c i p h e r C T R M o d e                                             %
00441 %                                                                             %
00442 %                                                                             %
00443 %                                                                             %
00444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00445 %
00446 %  DecipherCTRMode() deciphers with the cipher in Counter mode.  This mode is a
00447 %  confidentiality mode that features the application of the forward cipher to
00448 %  a set of input blocks, called counters, to produce a sequence of output
00449 %  blocks that are exclusive-ORed with the plaintext to produce the ciphertext,
00450 %  and vice versa. The sequence of counters must have the property that each
00451 %  block in the sequence is different from every other block. This condition is
00452 %  not restricted to a single message: across all of the messages that are
00453 %  enciphered under the given key, all of the counters must be distinct.
00454 %
00455 %  The format of the DecipherCTRMode method is:
00456 %
00457 %     StringInfo *DecipherCTRMode(CipherInfo *cipher_info,
00458 %       StringInfo *ciphertext)
00459 %
00460 %  A description of each parameter follows:
00461 %
00462 %    o cipher_info: The cipher context.
00463 %
00464 %    o ciphertext: The cipher text.
00465 %
00466 */
00467 
00468 static inline void IncrementCipherNonce(const size_t length,
00469   unsigned char *nonce)
00470 {
00471   register ssize_t
00472     i;
00473 
00474   for (i=(ssize_t) (length-1); i >= 0; i--)
00475   {
00476     nonce[i]++;
00477     if (nonce[i] != 0)
00478       return;
00479   }
00480   ThrowFatalException(CipherFatalError,"Sequence wrap error `%s'");
00481 }
00482 
00483 static StringInfo *DecipherCTRMode(CipherInfo *cipher_info,
00484   StringInfo *ciphertext)
00485 {
00486   register size_t
00487     i;
00488 
00489   register unsigned char
00490     *p,
00491     *q;
00492 
00493   size_t
00494     blocksize;
00495 
00496   StringInfo
00497     *plaintext;
00498 
00499   unsigned char
00500     input_block[MaxCipherBlocksize],
00501     output_block[MaxCipherBlocksize];
00502 
00503   /*
00504     Decipher in CTR mode.
00505   */
00506   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00507   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00508   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00509   blocksize=cipher_info->blocksize;
00510   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
00511   WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
00512   plaintext=ciphertext;
00513   p=GetStringInfoDatum(cipher_info->nonce);
00514   for (i=0; i < blocksize; i++)
00515     input_block[i]=p[i];
00516   q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
00517   for (p=GetStringInfoDatum(ciphertext); p < q; p+=blocksize)
00518   {
00519     for (i=0; i < blocksize; i++)
00520       output_block[i]=input_block[i];
00521     cipher_info->encipher_block(cipher_info->handle,output_block,output_block);
00522     for (i=0; i < blocksize; i++)
00523       p[i]^=output_block[i];
00524     IncrementCipherNonce(blocksize,input_block);
00525   }
00526   /*
00527     Reset registers.
00528   */
00529   (void) ResetWizardMemory(input_block,0,sizeof(input_block));
00530   (void) ResetWizardMemory(output_block,0,sizeof(output_block));
00531   return(plaintext);
00532 }
00533 
00534 /*
00535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00536 %                                                                             %
00537 %                                                                             %
00538 %                                                                             %
00539 +   D e c i p h e r E C B M o d e                                             %
00540 %                                                                             %
00541 %                                                                             %
00542 %                                                                             %
00543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00544 %
00545 %  DecipherECBMode() deciphers with the cipher in Electronic Codebook mode.
00546 %  This mode is a confidentiality mode that features, for a given key, the
00547 %  assignment of a fixed ciphertext block to each plaintext block, analogous to
00548 %  the assignment of code words in a codebook.
00549 %
00550 %  The format of the DecipherECBMode method is:
00551 %
00552 %     StringInfo *DecipherECBMode(CipherInfo *cipher_info,
00553 %       StringInfo *ciphertext)
00554 %
00555 %  A description of each parameter follows:
00556 %
00557 %    o cipher_info: The cipher context.
00558 %
00559 %    o ciphertext: The cipher text.
00560 %
00561 */
00562 static StringInfo *DecipherECBMode(CipherInfo *cipher_info,
00563   StringInfo *ciphertext)
00564 {
00565   register unsigned char
00566     *p,
00567     *q;
00568 
00569   size_t
00570     blocksize;
00571 
00572   StringInfo
00573     *plaintext;
00574 
00575   /*
00576     Decipher in ECB mode.
00577   */
00578   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00579   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00580   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00581   blocksize=cipher_info->blocksize;
00582   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
00583   WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
00584   plaintext=ciphertext;
00585   q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
00586   for (p=GetStringInfoDatum(ciphertext); p < q; p+=blocksize)
00587     cipher_info->decipher_block(cipher_info->handle,p,p);
00588   return(plaintext);
00589 }
00590 
00591 /*
00592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00593 %                                                                             %
00594 %                                                                             %
00595 %                                                                             %
00596 +   D e c i p h e r O F B M o d e                                             %
00597 %                                                                             %
00598 %                                                                             %
00599 %                                                                             %
00600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00601 %
00602 %  DecipherOFBMode() deciphers with the cipher in Output Feedback mode.  This
00603 %  mode is a confidentiality mode that features the iteration of the forward
00604 %  cipher on a nonce to generate a sequence of output blocks that are
00605 %  exclusive-ORed with the plaintext to produce the ciphertext, and vice versa.
00606 %  The OFB mode requires that the IV is a nonce, i.e., the IV must be unique
00607 %  for each execution of the mode under the given key.
00608 %
00609 %  The format of the DecipherOFBMode method is:
00610 %
00611 %     StringInfo *DecipherOFBMode(CipherInfo *cipher_info,
00612 %       StringInfo *ciphertext)
00613 %
00614 %  A description of each parameter follows:
00615 %
00616 %    o cipher_info: The cipher context.
00617 %
00618 %    o ciphertext: The cipher text.
00619 %
00620 */
00621 static StringInfo *DecipherOFBMode(CipherInfo *cipher_info,
00622   StringInfo *ciphertext)
00623 {
00624   register size_t
00625     i;
00626 
00627   register unsigned char
00628     *p,
00629     *q;
00630 
00631   size_t
00632     blocksize;
00633 
00634   StringInfo
00635     *plaintext;
00636 
00637   unsigned char
00638     input_block[MaxCipherBlocksize];
00639 
00640   /*
00641     Decipher in OFB mode.
00642   */
00643   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00644   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00645   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00646   blocksize=cipher_info->blocksize;
00647   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
00648   WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
00649   plaintext=ciphertext;
00650   p=GetStringInfoDatum(cipher_info->nonce);
00651   for (i=0; i < blocksize; i++)
00652     input_block[i]=p[i];
00653   q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
00654   for (p=GetStringInfoDatum(ciphertext); p < q; p+=blocksize)
00655   {
00656     cipher_info->encipher_block(cipher_info->handle,input_block,input_block);
00657     for (i=0; i < blocksize; i++)
00658       p[i]^=input_block[i];
00659   }
00660   /*
00661     Reset registers.
00662   */
00663   (void) ResetWizardMemory(input_block,0,sizeof(input_block));
00664   return(plaintext);
00665 }
00666 
00667 /*
00668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00669 %                                                                             %
00670 %                                                                             %
00671 %                                                                             %
00672 %   D e s t r o y C i p h e r I n f o                                         %
00673 %                                                                             %
00674 %                                                                             %
00675 %                                                                             %
00676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00677 %
00678 %  DestroyCipherInfo() zeros memory associated with the CipherInfo structure.
00679 %
00680 %  The format of the DestroyCipherInfo method is:
00681 %
00682 %      CipherInfo *DestroyCipherInfo(CipherInfo *cipher_info)
00683 %
00684 %  A description of each parameter follows:
00685 %
00686 %    o cipher_info: The cipher info.
00687 %
00688 */
00689 WizardExport CipherInfo *DestroyCipherInfo(CipherInfo *cipher_info)
00690 {
00691   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00692   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00693   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00694   if (cipher_info->handle != (CipherInfo *) NULL)
00695     switch (cipher_info->cipher)
00696     {
00697       case AESCipher:
00698       {
00699         cipher_info->handle=DestroyAESInfo((AESInfo *) cipher_info->handle);
00700         break;
00701       }
00702       case SerpentCipher:
00703       {
00704         cipher_info->handle=DestroySerpentInfo((SerpentInfo *)
00705           cipher_info->handle);
00706         break;
00707       }
00708       case TwofishCipher:
00709       {
00710         cipher_info->handle=DestroyTwofishInfo((TwofishInfo *)
00711           cipher_info->handle);
00712         break;
00713       }
00714       default:
00715         ThrowWizardFatalError(CipherDomain,EnumerateError);
00716     }
00717   if (cipher_info->nonce != (StringInfo *) NULL)
00718     cipher_info->nonce=DestroyStringInfo(cipher_info->nonce);
00719   if (cipher_info->random_info != (RandomInfo *) NULL)
00720     cipher_info->random_info=DestroyRandomInfo(cipher_info->random_info);
00721   cipher_info->signature=(~WizardSignature);
00722   cipher_info=(CipherInfo *) RelinquishWizardMemory(cipher_info);
00723   return(cipher_info);
00724 }
00725 
00726 /*
00727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00728 %                                                                             %
00729 %                                                                             %
00730 %                                                                             %
00731 +   E n c i p h e r C B C M o d e                                             %
00732 %                                                                             %
00733 %                                                                             %
00734 %                                                                             %
00735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00736 %
00737 %  EncipherCBCMode() enciphers with the cipher in Cipher Block Chaining mode.
00738 %  This mode is a confidentiality mode whose enciphering process features the
00739 %  combining ("chaining") of the plaintext blocks with the previous ciphertext
00740 %  blocks.  The CBC mode requires an IV to combine with the first plaintext
00741 %  block. The IV need not be secret, but it must be unpredictable.
00742 %
00743 %  The format of the EncipherCBCMode method is:
00744 %
00745 %      StringInfo *EncipherCBCMode(CipherInfo *cipher_info,
00746 %        StringInfo *plaintext)
00747 %
00748 %  A description of each parameter follows:
00749 %
00750 %    o cipher_info: The cipher context.
00751 %
00752 %    o plaintext: The plain text.
00753 %
00754 */
00755 static StringInfo *EncipherCBCMode(CipherInfo *cipher_info,
00756   StringInfo *plaintext)
00757 {
00758   register unsigned char
00759     *p,
00760     *q;
00761 
00762   register size_t
00763     i;
00764 
00765   size_t
00766     blocksize,
00767     pad;
00768 
00769   StringInfo
00770     *ciphertext;
00771 
00772   unsigned char
00773     input_block[MaxCipherBlocksize];
00774 
00775   /*
00776     Encipher in CBC mode.
00777   */
00778   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00779   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00780   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00781   blocksize=cipher_info->blocksize;
00782   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
00783   WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
00784   ciphertext=plaintext;
00785   p=GetStringInfoDatum(cipher_info->nonce);
00786   for (i=0; i < blocksize; i++)
00787     input_block[i]=p[i];
00788   q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
00789   pad=blocksize-GetStringInfoLength(plaintext) % blocksize;
00790   SetRandomKey(cipher_info->random_info,pad-1,q);
00791   q[pad-1]=(unsigned char) (pad-1);
00792   if (pad == blocksize)
00793     q+=blocksize;
00794   for (p=GetStringInfoDatum(plaintext); p < q; p+=blocksize)
00795   {
00796     for (i=0; i < blocksize; i++)
00797       p[i]^=input_block[i];
00798     cipher_info->encipher_block(cipher_info->handle,p,p);
00799     for (i=0; i < blocksize; i++)
00800       input_block[i]=p[i];
00801   }
00802   /*
00803     Reset registers.
00804   */
00805   (void) ResetWizardMemory(input_block,0,sizeof(input_block));
00806   return(ciphertext);
00807 }
00808 
00809 /*
00810 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00811 %                                                                             %
00812 %                                                                             %
00813 %                                                                             %
00814 +   E n c i p h e r C F B M o d e                                             %
00815 %                                                                             %
00816 %                                                                             %
00817 %                                                                             %
00818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00819 %
00820 %  EncipherCFBMode() enciphers with the cipher in Cipher Feedback mode.  This
00821 %  mode is a confidentiality mode that features the feedback of successive
00822 %  ciphertext segments into the input blocks of the forward cipher to generate
00823 %  output blocks that are exclusive-ORed with the plaintext to produce the
00824 %  ciphertext, and vice versa. The CFB mode requires a nonce as the initial
00825 %  input block. The nonce need not be secret, but it must be unpredictable.
00826 %
00827 %  The format of the EncipherCFBMode method is:
00828 %
00829 %      StringInfo *EncipherCFBMode(CipherInfo *cipher_info,
00830 %        StringInfo *plaintext)
00831 %
00832 %  A description of each parameter follows:
00833 %
00834 %    o cipher_info: The cipher context.
00835 %
00836 %    o plaintext: The plain text.
00837 %
00838 */
00839 static StringInfo *EncipherCFBMode(CipherInfo *cipher_info,
00840   StringInfo *plaintext)
00841 {
00842   register size_t
00843     i;
00844 
00845   register unsigned char
00846     *p,
00847     *q;
00848 
00849   size_t
00850     blocksize;
00851 
00852   StringInfo
00853     *ciphertext;
00854 
00855   unsigned char
00856     input_block[MaxCipherBlocksize],
00857     output_block[MaxCipherBlocksize];
00858 
00859   /*
00860     Encipher in CFB mode.
00861   */
00862   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00863   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00864   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00865   blocksize=cipher_info->blocksize;
00866   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
00867   WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
00868   ciphertext=plaintext;
00869   p=GetStringInfoDatum(cipher_info->nonce);
00870   for (i=0; i < blocksize; i++)
00871     input_block[i]=p[i];
00872   q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
00873   for (p=GetStringInfoDatum(plaintext); p < q; p++)
00874   {
00875     for (i=0; i < blocksize; i++)
00876       output_block[i]=input_block[i];
00877     cipher_info->encipher_block(cipher_info->handle,output_block,output_block);
00878     *p^=(*output_block);
00879     for (i=0; i < (blocksize-1); i++)
00880       input_block[i]=input_block[i+1];
00881     input_block[blocksize-1]=(*p);
00882   }
00883   /*
00884     Reset registers.
00885   */
00886   (void) ResetWizardMemory(input_block,0,sizeof(input_block));
00887   (void) ResetWizardMemory(output_block,0,sizeof(output_block));
00888   return(ciphertext);
00889 }
00890 
00891 /*
00892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00893 %                                                                             %
00894 %                                                                             %
00895 %                                                                             %
00896 %   E n c i p h e r C i p h e r                                               %
00897 %                                                                             %
00898 %                                                                             %
00899 %                                                                             %
00900 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00901 %
00902 %  EncipherCipher() enciphers plaintext and returns ciphertext.  The
00903 %  enciphering is performed in-place and EncipherCipher() returns a pointer to
00904 %  the plaintext string.
00905 %
00906 %  The format of the EncipherCipher method is:
00907 %
00908 %     StringInfo *EncipherCipher(CipherInfo *cipher_info,StringInfo *plaintext)
00909 %
00910 %  A description of each parameter follows:
00911 %
00912 %    o cipher_info: The cipher context.
00913 %
00914 %    o plaintext: The plain text.
00915 %
00916 */
00917 
00918 WizardExport StringInfo *EncryptCipher(CipherInfo *cipher_info,
00919   StringInfo *plaintext)
00920 {
00921   return(EncipherCipher(cipher_info,plaintext));
00922 }
00923 
00924 WizardExport StringInfo *EncipherCipher(CipherInfo *cipher_info,
00925   StringInfo *plaintext)
00926 {
00927   StringInfo
00928     *ciphertext;
00929 
00930   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00931   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
00932   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
00933   WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
00934   ciphertext=(StringInfo *) NULL;
00935   switch (cipher_info->mode)
00936   {
00937     case CBCMode:
00938     {
00939       ciphertext=EncipherCBCMode(cipher_info,plaintext);
00940       break;
00941     }
00942     case CFBMode:
00943     {
00944       ciphertext=EncipherCFBMode(cipher_info,plaintext);
00945       break;
00946     }
00947     case CTRMode:
00948     {
00949       ciphertext=EncipherCTRMode(cipher_info,plaintext);
00950       break;
00951     }
00952     case ECBMode:
00953     {
00954       ciphertext=EncipherECBMode(cipher_info,plaintext);
00955       break;
00956     }
00957     case OFBMode:
00958     {
00959       ciphertext=EncipherOFBMode(cipher_info,plaintext);
00960       break;
00961     }
00962     default:
00963       ThrowWizardFatalError(CipherDomain,EnumerateError);
00964   }
00965   return(ciphertext);
00966 }
00967 
00968 /*
00969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00970 %                                                                             %
00971 %                                                                             %
00972 %                                                                             %
00973 +   E n c i p h e r C T R M o d e                                             %
00974 %                                                                             %
00975 %                                                                             %
00976 %                                                                             %
00977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00978 %
00979 %  EncipherCTRMode() enciphers with the cipher in Counter mode.  This mode is a
00980 %  confidentiality mode that features the application of the forward cipher to
00981 %  a set of input blocks, called counters, to produce a sequence of output
00982 %  blocks that are exclusive-ORed with the plaintext to produce the ciphertext,
00983 %  and vice versa. The sequence of counters must have the property that each
00984 %  block in the sequence is different from every other block. This condition is
00985 %  not restricted to a single message: across all of the messages that are
00986 %  enciphered under the given key, all of the counters must be distinct.
00987 %
00988 %  The format of the EncipherCTRMode method is:
00989 %
00990 %      StringInfo *EncipherCTRMode(CipherInfo *cipher_info,
00991 %        StringInfo *plaintext)
00992 %
00993 %  A description of each parameter follows:
00994 %
00995 %    o cipher_info: The cipher context.
00996 %
00997 %    o plaintext: The plain text.
00998 %
00999 */
01000 static StringInfo *EncipherCTRMode(CipherInfo *cipher_info,
01001   StringInfo *plaintext)
01002 {
01003   register size_t
01004     i;
01005 
01006   register unsigned char
01007     *p,
01008     *q;
01009 
01010   size_t
01011     blocksize,
01012     pad;
01013 
01014   StringInfo
01015     *ciphertext;
01016 
01017   unsigned char
01018     input_block[MaxCipherBlocksize],
01019     output_block[MaxCipherBlocksize];
01020 
01021   /*
01022     Encipher in CTR mode.
01023   */
01024   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01025   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
01026   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
01027   blocksize=cipher_info->blocksize;
01028   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
01029   WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
01030   ciphertext=plaintext;
01031   p=GetStringInfoDatum(cipher_info->nonce);
01032   for (i=0; i < blocksize; i++)
01033     input_block[i]=p[i];
01034   q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
01035   pad=blocksize-GetStringInfoLength(plaintext) % blocksize;
01036   SetRandomKey(cipher_info->random_info,pad-1,q);
01037   q[pad-1]=(unsigned char) (pad-1);
01038   if (pad == blocksize)
01039     q+=blocksize;
01040   for (p=GetStringInfoDatum(plaintext); p < q; p+=blocksize)
01041   {
01042     for (i=0; i < blocksize; i++)
01043       output_block[i]=input_block[i];
01044     cipher_info->encipher_block(cipher_info->handle,output_block,output_block);
01045     for (i=0; i < blocksize; i++)
01046       p[i]^=output_block[i];
01047     IncrementCipherNonce(blocksize,input_block);
01048   }
01049   /*
01050     Reset registers.
01051   */
01052   (void) ResetWizardMemory(input_block,0,sizeof(input_block));
01053   (void) ResetWizardMemory(output_block,0,sizeof(output_block));
01054   return(ciphertext);
01055 }
01056 
01057 /*
01058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01059 %                                                                             %
01060 %                                                                             %
01061 %                                                                             %
01062 +   E n c i p h e r E C B M o d e                                             %
01063 %                                                                             %
01064 %                                                                             %
01065 %                                                                             %
01066 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01067 %
01068 %  EncipherECBMode() enciphers with the cipher in Electronic Codebook mode.
01069 %  This mode is a confidentiality mode that features, for a given key, the
01070 %  assignment of a fixed ciphertext block to each plaintext block, analogous to
01071 %  the assignment of code words in a codebook.
01072 %
01073 %  The format of the EncipherECBMode method is:
01074 %
01075 %      StringInfo *EncipherECBMode(CipherInfo *cipher_info,
01076 %        StringInfo *plaintext)
01077 %
01078 %  A description of each parameter follows:
01079 %
01080 %    o cipher_info: The cipher context.
01081 %
01082 %    o plaintext: The plain text.
01083 %
01084 */
01085 static StringInfo *EncipherECBMode(CipherInfo *cipher_info,
01086   StringInfo *plaintext)
01087 {
01088   register unsigned char
01089     *p,
01090     *q;
01091 
01092   size_t
01093     blocksize,
01094     pad;
01095 
01096   StringInfo
01097     *ciphertext;
01098 
01099   /*
01100     Encipher in ECB mode.
01101   */
01102   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01103   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
01104   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
01105   blocksize=cipher_info->blocksize;
01106   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
01107   WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
01108   ciphertext=plaintext;
01109   q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
01110   pad=blocksize-GetStringInfoLength(plaintext) % blocksize;
01111   SetRandomKey(cipher_info->random_info,pad-1,q);
01112   q[pad-1]=(unsigned char) (pad-1);
01113   if (pad == blocksize)
01114     q+=blocksize;
01115   for (p=GetStringInfoDatum(plaintext); p < q; p+=blocksize)
01116     cipher_info->encipher_block(cipher_info->handle,p,p);
01117   return(ciphertext);
01118 }
01119 
01120 /*
01121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01122 %                                                                             %
01123 %                                                                             %
01124 %                                                                             %
01125 +   E n c i p h e r O F B M o d e                                             %
01126 %                                                                             %
01127 %                                                                             %
01128 %                                                                             %
01129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01130 %
01131 %  EncipherOFBMode() enciphers with the cipher in Output Feedback mode.  This
01132 %  mode is a confidentiality mode that features the iteration of the forward
01133 %  cipher on a nonce to generate a sequence of output blocks that are
01134 %  exclusive-ORed with the plaintext to produce the ciphertext, and vice versa.
01135 %  The OFB mode requires that the IV is a nonce, i.e., the IV must be unique
01136 %  for each execution of the mode under the given key.
01137 %
01138 %  The format of the EncipherOFBMode method is:
01139 %
01140 %      StringInfo *EncipherOFBMode(CipherInfo *cipher_info,
01141 %        StringInfo *plaintext)
01142 %
01143 %  A description of each parameter follows:
01144 %
01145 %    o cipher_info: The cipher context.
01146 %
01147 %    o plaintext: The plain text.
01148 %
01149 */
01150 static StringInfo *EncipherOFBMode(CipherInfo *cipher_info,
01151   StringInfo *plaintext)
01152 {
01153   register size_t
01154     i;
01155 
01156   register unsigned char
01157     *p,
01158     *q;
01159 
01160   size_t
01161     blocksize,
01162     pad;
01163 
01164   StringInfo
01165     *ciphertext;
01166 
01167   unsigned char
01168     input_block[MaxCipherBlocksize];
01169 
01170   /*
01171     Encipher in OBC mode.
01172   */
01173   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01174   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
01175   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
01176   blocksize=cipher_info->blocksize;
01177   WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
01178   WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
01179   ciphertext=plaintext;
01180   p=GetStringInfoDatum(cipher_info->nonce);
01181   for (i=0; i < blocksize; i++)
01182     input_block[i]=p[i];
01183   q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
01184   pad=blocksize-GetStringInfoLength(plaintext) % blocksize;
01185   SetRandomKey(cipher_info->random_info,pad-1,q);
01186   q[pad-1]=(unsigned char) (pad-1);
01187   if (pad == blocksize)
01188     q+=blocksize;
01189   for (p=GetStringInfoDatum(plaintext); p < q; p+=blocksize)
01190   {
01191     cipher_info->encipher_block(cipher_info->handle,input_block,input_block);
01192     for (i=0; i < blocksize; i++)
01193       p[i]^=input_block[i];
01194   }
01195   /*
01196     Reset registers.
01197   */
01198   (void) ResetWizardMemory(input_block,0,sizeof(input_block));
01199   return(ciphertext);
01200 }
01201 
01202 /*
01203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01204 %                                                                             %
01205 %                                                                             %
01206 %                                                                             %
01207 %   G e t C i p h e r B l o c k s i z e                                       %
01208 %                                                                             %
01209 %                                                                             %
01210 %                                                                             %
01211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01212 %
01213 %  GetCipherBlocksize() returns the cipher blocksize.
01214 %
01215 %  The format of the GetCipherBlocksize method is:
01216 %
01217 %      size_t GetCipherBlocksize(const CipherInfo *cipher_info)
01218 %
01219 %  A description of each parameter follows:
01220 %
01221 %    o cipher_info: The cipher info.
01222 %
01223 */
01224 WizardExport size_t GetCipherBlocksize(const CipherInfo *cipher_info)
01225 {
01226   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01227   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
01228   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
01229   return(cipher_info->blocksize);
01230 }
01231 
01232 /*
01233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01234 %                                                                             %
01235 %                                                                             %
01236 %                                                                             %
01237 %   G e n e r a t e C i p h e r N o n c e                                     %
01238 %                                                                             %
01239 %                                                                             %
01240 %                                                                             %
01241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01242 %
01243 %  GenerateCipherNonce() generate a nonce for the given cipher.
01244 %
01245 %  The format of the GenerateCipherNonce method is:
01246 %
01247 %     StringInfo *GenerateCipherNonce(CipherInfo *cipher_info)
01248 %
01249 %  A description of each parameter follows:
01250 %
01251 %    o cipher_info: The cipher context.
01252 %
01253 */
01254 WizardExport StringInfo *GenerateCipherNonce(CipherInfo *cipher_info)
01255 {
01256   StringInfo
01257     *nonce;
01258 
01259   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01260   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
01261   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
01262   switch (cipher_info->mode)
01263   {
01264     case CBCMode:
01265     case CFBMode:
01266     case ECBMode:
01267     case OFBMode:
01268     {
01269       nonce=GetRandomKey(cipher_info->random_info,cipher_info->blocksize);
01270       break;
01271     }
01272     case CTRMode:
01273     {
01274       nonce=AcquireStringInfo(cipher_info->blocksize);
01275       ResetStringInfo(nonce);
01276       SetRandomKey(cipher_info->random_info,(cipher_info->blocksize+1)/2,
01277         GetStringInfoDatum(nonce));
01278       break;
01279     }
01280     default:
01281       ThrowWizardFatalError(CipherDomain,EnumerateError);
01282   }
01283   return(nonce);
01284 }
01285 
01286 /*
01287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01288 %                                                                             %
01289 %                                                                             %
01290 %                                                                             %
01291 %   G e t C i p h e r N o n c e                                               %
01292 %                                                                             %
01293 %                                                                             %
01294 %                                                                             %
01295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01296 %
01297 %  GetCipherNonce() returns a nonce of the cipher.
01298 %
01299 %  The format of the GetCipherNonce method is:
01300 %
01301 %     const StringInfo *GetCipherNonce(CipherInfo *cipher_info)
01302 %
01303 %  A description of each parameter follows:
01304 %
01305 %    o cipher_info: The cipher context.
01306 %
01307 */
01308 WizardExport const StringInfo *GetCipherNonce(CipherInfo *cipher_info)
01309 {
01310   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01311   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
01312   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
01313   return(cipher_info->nonce);
01314 }
01315 
01316 /*
01317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01318 %                                                                             %
01319 %                                                                             %
01320 %                                                                             %
01321 %   R e s e t C i p h e r N o n c e                                           %
01322 %                                                                             %
01323 %                                                                             %
01324 %                                                                             %
01325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01326 %
01327 %  ResetCipherNonce() resets the initialization vector for the cipher.
01328 %
01329 %  The format of the ResetCipherNonce method is:
01330 %
01331 %      ResetCipherNonce(CipherInfo *cipher_info)
01332 %
01333 %  A description of each parameter follows:
01334 %
01335 %    o cipher_info: The cipher context.
01336 %
01337 */
01338 WizardExport void ResetCipherNonce(CipherInfo *cipher_info)
01339 {
01340   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01341   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
01342   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
01343   ResetStringInfo(cipher_info->nonce);
01344 }
01345 
01346 /*
01347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01348 %                                                                             %
01349 %                                                                             %
01350 %                                                                             %
01351 %   S e t C i p h e r N o n c e                                               %
01352 %                                                                             %
01353 %                                                                             %
01354 %                                                                             %
01355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01356 %
01357 %  SetCipherNonce() sets the initialization vector for the cipher.
01358 %
01359 %  The format of the SetCipherNonce method is:
01360 %
01361 %      SetCipherNonce(CipherInfo *cipher_info,const StringInfo *nonce)
01362 %
01363 %  A description of each parameter follows:
01364 %
01365 %    o cipher_info: The cipher context.
01366 %
01367 %    o nonce: The initialization vector.
01368 %
01369 */
01370 WizardExport void SetCipherNonce(CipherInfo *cipher_info,
01371   const StringInfo *nonce)
01372 {
01373   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01374   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
01375   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
01376   WizardAssert(CipherDomain,nonce != (StringInfo *) NULL);
01377   SetStringInfo(cipher_info->nonce,nonce);
01378 }
01379 
01380 /*
01381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01382 %                                                                             %
01383 %                                                                             %
01384 %                                                                             %
01385 %   S e t C i p h e r K e y                                                   %
01386 %                                                                             %
01387 %                                                                             %
01388 %                                                                             %
01389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01390 %
01391 %  SetCipherKey() sets the key for the cipher.  The key length is specified
01392 %  in bits.  Valid values are 128, 192, or 256.
01393 %
01394 %  The format of the SetCipherKey method is:
01395 %
01396 %      SetCipherKey(CipherInfo *cipher_info,const StringInfo *key)
01397 %
01398 %  A description of each parameter follows:
01399 %
01400 %    o cipher_info: The cipher context.
01401 %
01402 %    o key: The key.
01403 %
01404 */
01405 WizardExport void SetCipherKey(CipherInfo *cipher_info,const StringInfo *key)
01406 {
01407   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01408   WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
01409   WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
01410   WizardAssert(CipherDomain,key != (StringInfo *) NULL);
01411   switch (cipher_info->cipher)
01412   {
01413     case AESCipher:
01414     {
01415       SetAESKey((AESInfo *) cipher_info->handle,key);
01416       break;
01417     }
01418     case SerpentCipher:
01419     {
01420       SetSerpentKey((SerpentInfo *) cipher_info->handle,key);
01421       break;
01422     }
01423     case TwofishCipher:
01424     {
01425       SetTwofishKey((TwofishInfo *) cipher_info->handle,key);
01426       break;
01427     }
01428     default:
01429       ThrowWizardFatalError(CipherDomain,EnumerateError);
01430   }
01431 }