|
WizardsToolkit
1.0.7
|
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 }