root/WizardsToolkit/trunk/wizard/cipher.c

Revision 256, 49.3 KB (checked in by cristy, 8 weeks ago)
Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                   CCCC  IIIII  PPPP   H   H  EEEEE  RRRR                    %
6%                  C        I    P   P  H   H  E      R   R                   %
7%                  C        I    PPPP   HHHHH  EEE    RRRR                    %
8%                  C        I    P      H   H  E      R R                     %
9%                   CCCC  IIIII  P      H   H  EEEEE  R  R                    %
10%                                                                             %
11%                                                                             %
12%              Wizard's Toolkit Secure Cipher Algorithm Methods               %
13%                                                                             %
14%                             Software Design                                 %
15%                               John Cristy                                   %
16%                               March  2003                                   %
17%                                                                             %
18%                                                                             %
19%  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
20%  dedicated to making software imaging solutions freely available.           %
21%                                                                             %
22%  You may not use this file except in compliance with the License.  You may  %
23%  obtain a copy of the License at                                            %
24%                                                                             %
25%    http://www.wizards-toolkit.org/script/license.php                        %
26%                                                                             %
27%  Unless required by applicable law or agreed to in writing, software        %
28%  distributed under the License is distributed on an "AS IS" BASIS,          %
29%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
30%  See the License for the specific language governing permissions and        %
31%  limitations under the License.                                             %
32%                                                                             %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35% See http://csrc.nist.gov/cryptval/shs.htm.
36%
37*/
38
39/*
40  Include declarations.
41*/
42#include "wizard/studio.h"
43#include "wizard/aes.h"
44#include "wizard/cipher.h"
45#include "wizard/exception.h"
46#include "wizard/exception-private.h"
47#include "wizard/memory_.h"
48#include "wizard/random_.h"
49#include "wizard/serpent.h"
50#include "wizard/twofish.h"
51
52/*
53  Define declarations.
54*/
55#define CipherRandomHash  SHA256Hash
56
57/*
58  Typedef declarations.
59*/
60typedef void
61  (*DecipherBlock)(void *,const unsigned char *,const unsigned char *),
62  (*EncipherBlock)(void *,const unsigned char *,const unsigned char *);
63
64struct _CipherInfo
65{
66  void
67    *handle;
68
69  CipherType
70    cipher;
71
72  CipherMode
73    mode;
74
75  size_t
76    blocksize;
77
78  DecipherBlock
79    decipher_block;
80
81  DecipherBlock
82    encipher_block;
83
84  StringInfo
85    *nonce;
86
87  RandomInfo
88    *random_info;
89
90  time_t
91    timestamp;
92
93  unsigned long
94    signature;
95};
96
97/*
98  Forward declaration.
99*/
100static StringInfo
101  *DecipherCTRMode(CipherInfo *,StringInfo *),
102  *DecipherECBMode(CipherInfo *,StringInfo *),
103  *DecipherOFBMode(CipherInfo *,StringInfo *),
104  *EncipherCTRMode(CipherInfo *,StringInfo *),
105  *EncipherECBMode(CipherInfo *,StringInfo *),
106  *EncipherOFBMode(CipherInfo *,StringInfo *);
107
108/*
109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110%                                                                             %
111%                                                                             %
112%                                                                             %
113%   A c q u i r e C i p h e r I n f o                                         %
114%                                                                             %
115%                                                                             %
116%                                                                             %
117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118%
119%  AcquireCipherInfo() allocates the CipherInfo structure.
120%
121%  The format of the AcquireCipherInfo method is:
122%
123%      CipherInfo *AcquireCipherInfo(const CipherType cipher,
124%        const CipherMode mode)
125%
126%  A description of each parameter follows:
127%
128%    o cipher: The cipher type.
129%
130%    o mode: The cipher mode.
131%
132*/
133WizardExport CipherInfo *AcquireCipherInfo(const CipherType cipher,
134  const CipherMode mode)
135{
136  CipherInfo
137    *cipher_info;
138
139  cipher_info=(CipherInfo *) AcquireWizardMemory(sizeof(*cipher_info));
140  if (cipher_info == (CipherInfo *) NULL)
141    ThrowWizardFatalError(CipherDomain,MemoryError);
142  (void) ResetWizardMemory(cipher_info,0,sizeof(*cipher_info));
143  cipher_info->cipher=cipher;
144  switch (cipher_info->cipher)
145  {
146    case AESCipher:
147    {
148      AESInfo
149        *aes_info;
150
151      aes_info=AcquireAESInfo();
152      cipher_info->handle=(CipherInfo *) aes_info;
153      cipher_info->blocksize=GetAESBlocksize(aes_info);
154      cipher_info->decipher_block=(DecipherBlock) DecipherAESBlock;
155      cipher_info->encipher_block=(DecipherBlock) EncipherAESBlock;
156      break;
157    }
158    case SerpentCipher:
159    {
160      SerpentInfo
161        *serpent_info;
162
163      serpent_info=AcquireSerpentInfo();
164      cipher_info->handle=(CipherInfo *) serpent_info;
165      cipher_info->blocksize=GetSerpentBlocksize(serpent_info);
166      cipher_info->decipher_block=(DecipherBlock) DecipherSerpentBlock;
167      cipher_info->encipher_block=(DecipherBlock) EncipherSerpentBlock;
168      break;
169    }
170    case TwofishCipher:
171    {
172      TwofishInfo
173        *twofish_info;
174
175      twofish_info=AcquireTwofishInfo();
176      cipher_info->handle=(CipherInfo *) twofish_info;
177      cipher_info->blocksize=GetTwofishBlocksize(twofish_info);
178      cipher_info->decipher_block=(DecipherBlock) DecipherTwofishBlock;
179      cipher_info->encipher_block=(DecipherBlock) EncipherTwofishBlock;
180      break;
181    }
182    default:
183      ThrowWizardFatalError(CipherDomain,EnumerateError);
184  }
185  cipher_info->mode=mode;
186  if (cipher_info->nonce != (StringInfo *) NULL)
187    cipher_info->nonce=DestroyStringInfo(cipher_info->nonce);
188  cipher_info->random_info=AcquireRandomInfo(CipherRandomHash);
189  cipher_info->timestamp=time((time_t *) NULL);
190  cipher_info->signature=WizardSignature;
191  cipher_info->nonce=GenerateCipherNonce(cipher_info);
192  return(cipher_info);
193}
194
195/*
196%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197%                                                                             %
198%                                                                             %
199%                                                                             %
200+   D e c i p h e r C B C M o d e                                             %
201%                                                                             %
202%                                                                             %
203%                                                                             %
204%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205%
206%  DecipherCBCMode() deciphers with the cipher in Cipher Block Chaining mode.
207%  This mode is a confidentiality mode whose enciphering process features the
208%  combining ("chaining") of the plaintext blocks with the previous ciphertext
209%  blocks.  The CBC mode requires an IV to combine with the first plaintext
210%  block. The IV need not be secret, but it must be unpredictable.
211%
212%  The format of the DecipherCBCMode method is:
213%
214%     StringInfo *DecipherCBCMode(CipherInfo *cipher_info,
215%       StringInfo *ciphertext)
216%
217%  A description of each parameter follows:
218%
219%    o cipher_info: The cipher context.
220%
221%    o ciphertext: The cipher text.
222%
223*/
224static StringInfo *DecipherCBCMode(CipherInfo *cipher_info,
225  StringInfo *ciphertext)
226{
227  register size_t
228    i;
229
230  register unsigned char
231    *p,
232    *q;
233
234  size_t
235    blocksize;
236
237  StringInfo
238    *plaintext;
239
240  unsigned char
241    input_block[MaxCipherBlocksize],
242    output_block[MaxCipherBlocksize];
243
244  /*
245    Decipher in CBC mode.
246  */
247  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
248  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
249  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
250  blocksize=cipher_info->blocksize;
251  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
252  WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
253  plaintext=ciphertext;
254  p=GetStringInfoDatum(cipher_info->nonce);
255  for (i=0; i < blocksize; i++)
256    input_block[i]=p[i];
257  q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
258  for (p=GetStringInfoDatum(ciphertext); p < q; p+=blocksize)
259  {
260    for (i=0; i < blocksize; i++)
261      output_block[i]=p[i];
262    cipher_info->decipher_block(cipher_info->handle,p,p);
263    for (i=0; i < blocksize; i++)
264      p[i]^=input_block[i];
265    for (i=0; i < blocksize; i++)
266      input_block[i]=output_block[i];
267  }
268  /*
269    Reset registers.
270  */
271  (void) ResetWizardMemory(input_block,0,sizeof(input_block));
272  (void) ResetWizardMemory(output_block,0,sizeof(output_block));
273  return(plaintext);
274}
275
276/*
277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278%                                                                             %
279%                                                                             %
280%                                                                             %
281+   D e c i p h e r C F B M o d e                                             %
282%                                                                             %
283%                                                                             %
284%                                                                             %
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286%
287%  DecipherCFBMode() deciphers with the cipher in Cipher Feedback mode. This
288%  mode is a confidentiality mode that features the feedback of successive
289%  ciphertext segments into the input blocks of the forward cipher to generate
290%  output blocks that are exclusive-ORed with the plaintext to produce the
291%  ciphertext, and vice versa. The CFB mode requires an IV as the initial
292%  input block. The IV need not be secret, but it must be unpredictable.
293%
294%  The format of the DecipherCFBMode method is:
295%
296%     StringInfo *DecipherCFBMode(CipherInfo *cipher_info,
297%       StringInfo *ciphertext)
298%
299%  A description of each parameter follows:
300%
301%    o cipher_info: The cipher context.
302%
303%    o ciphertext: The cipher text.
304%
305*/
306static StringInfo *DecipherCFBMode(CipherInfo *cipher_info,
307  StringInfo *ciphertext)
308{
309  register size_t
310    i;
311
312  register unsigned char
313    *p,
314    *q;
315
316  size_t
317    blocksize;
318
319  StringInfo
320    *plaintext;
321
322  unsigned char
323    input_block[MaxCipherBlocksize],
324    output_block[MaxCipherBlocksize];
325
326  /*
327    Decipher in CFB mode.
328  */
329  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
330  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
331  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
332  blocksize=cipher_info->blocksize;
333  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
334  WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
335  plaintext=ciphertext;
336  p=GetStringInfoDatum(cipher_info->nonce);
337  for (i=0; i < blocksize; i++)
338    input_block[i]=p[i];
339  q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
340  for (p=GetStringInfoDatum(ciphertext); p < q; p++)
341  {
342    for (i=0; i < blocksize; i++)
343      output_block[i]=input_block[i];
344    cipher_info->encipher_block(cipher_info->handle,output_block,output_block);
345    for (i=0; i < (blocksize-1); i++)
346      input_block[i]=input_block[i+1];
347    input_block[blocksize-1]=(*p);
348    *p^=(*output_block);
349  }
350  /*
351    Reset registers.
352  */
353  (void) ResetWizardMemory(input_block,0,sizeof(input_block));
354  (void) ResetWizardMemory(output_block,0,sizeof(output_block));
355  return(plaintext);
356}
357
358/*
359%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
360%                                                                             %
361%                                                                             %
362%                                                                             %
363%   D e c i p h e r C i p h e r                                               %
364%                                                                             %
365%                                                                             %
366%                                                                             %
367%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368%
369%  DecipherCipher() deciphers ciphertext and returns plaintext. The deciphering
370%  is performed in-place and DecipherCipher() returns a pointer to the
371%  ciphertext string.
372%
373%  The format of the DecipherCipher method is:
374%
375%     StringInfo *DecipherCipher(CipherInfo *cipher_info,StringInfo *ciphertext)
376%
377%  A description of each parameter follows:
378%
379%    o cipher_info: The cipher context.
380%
381%    o ciphertext: The cipher text.
382%
383*/
384
385WizardExport StringInfo *DecryptCipher(CipherInfo *cipher_info,
386  StringInfo *plaintext)
387{
388  return(DecipherCipher(cipher_info,plaintext));
389}
390
391WizardExport StringInfo *DecipherCipher(CipherInfo *cipher_info,
392  StringInfo *ciphertext)
393{
394  StringInfo
395    *plaintext;
396
397  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
398  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
399  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
400  WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
401  plaintext=(StringInfo *) NULL;
402  switch (cipher_info->mode)
403  {
404    case CBCMode:
405    {
406      plaintext=DecipherCBCMode(cipher_info,ciphertext);
407      break;
408    }
409    case CFBMode:
410    {
411      plaintext=DecipherCFBMode(cipher_info,ciphertext);
412      break;
413    }
414    case CTRMode:
415    {
416      plaintext=DecipherCTRMode(cipher_info,ciphertext);
417      break;
418    }
419    case ECBMode:
420    {
421      plaintext=DecipherECBMode(cipher_info,ciphertext);
422      break;
423    }
424    case OFBMode:
425    {
426      plaintext=DecipherOFBMode(cipher_info,ciphertext);
427      break;
428    }
429    default:
430      ThrowWizardFatalError(CipherDomain,EnumerateError);
431  }
432  return(plaintext);
433}
434
435/*
436%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
437%                                                                             %
438%                                                                             %
439%                                                                             %
440+   D e c i p h e r C T R M o d e                                             %
441%                                                                             %
442%                                                                             %
443%                                                                             %
444%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
445%
446%  DecipherCTRMode() deciphers with the cipher in Counter mode.  This mode is a
447%  confidentiality mode that features the application of the forward cipher to
448%  a set of input blocks, called counters, to produce a sequence of output
449%  blocks that are exclusive-ORed with the plaintext to produce the ciphertext,
450%  and vice versa. The sequence of counters must have the property that each
451%  block in the sequence is different from every other block. This condition is
452%  not restricted to a single message: across all of the messages that are
453%  enciphered under the given key, all of the counters must be distinct.
454%
455%  The format of the DecipherCTRMode method is:
456%
457%     StringInfo *DecipherCTRMode(CipherInfo *cipher_info,
458%       StringInfo *ciphertext)
459%
460%  A description of each parameter follows:
461%
462%    o cipher_info: The cipher context.
463%
464%    o ciphertext: The cipher text.
465%
466*/
467
468static inline void IncrementCipherNonce(const size_t length,
469  unsigned char *nonce)
470{
471  register long
472    i;
473
474  for (i=(long) (length-1); i >= 0; i--)
475  {
476    nonce[i]++;
477    if (nonce[i] != 0)
478      return;
479  }
480  ThrowFatalException(CipherFatalError,"Sequence wrap error `%s'");
481}
482
483static StringInfo *DecipherCTRMode(CipherInfo *cipher_info,
484  StringInfo *ciphertext)
485{
486  register size_t
487    i;
488
489  register unsigned char
490    *p,
491    *q;
492
493  size_t
494    blocksize;
495
496  StringInfo
497    *plaintext;
498
499  unsigned char
500    input_block[MaxCipherBlocksize],
501    output_block[MaxCipherBlocksize];
502
503  /*
504    Decipher in CTR mode.
505  */
506  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
507  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
508  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
509  blocksize=cipher_info->blocksize;
510  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
511  WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
512  plaintext=ciphertext;
513  p=GetStringInfoDatum(cipher_info->nonce);
514  for (i=0; i < blocksize; i++)
515    input_block[i]=p[i];
516  q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
517  for (p=GetStringInfoDatum(ciphertext); p < q; p+=blocksize)
518  {
519    for (i=0; i < blocksize; i++)
520      output_block[i]=input_block[i];
521    cipher_info->encipher_block(cipher_info->handle,output_block,output_block);
522    for (i=0; i < blocksize; i++)
523      p[i]^=output_block[i];
524    IncrementCipherNonce(blocksize,input_block);
525  }
526  /*
527    Reset registers.
528  */
529  (void) ResetWizardMemory(input_block,0,sizeof(input_block));
530  (void) ResetWizardMemory(output_block,0,sizeof(output_block));
531  return(plaintext);
532}
533
534/*
535%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
536%                                                                             %
537%                                                                             %
538%                                                                             %
539+   D e c i p h e r E C B M o d e                                             %
540%                                                                             %
541%                                                                             %
542%                                                                             %
543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544%
545%  DecipherECBMode() deciphers with the cipher in Electronic Codebook mode.
546%  This mode is a confidentiality mode that features, for a given key, the
547%  assignment of a fixed ciphertext block to each plaintext block, analogous to
548%  the assignment of code words in a codebook.
549%
550%  The format of the DecipherECBMode method is:
551%
552%     StringInfo *DecipherECBMode(CipherInfo *cipher_info,
553%       StringInfo *ciphertext)
554%
555%  A description of each parameter follows:
556%
557%    o cipher_info: The cipher context.
558%
559%    o ciphertext: The cipher text.
560%
561*/
562static StringInfo *DecipherECBMode(CipherInfo *cipher_info,
563  StringInfo *ciphertext)
564{
565  register unsigned char
566    *p,
567    *q;
568
569  size_t
570    blocksize;
571
572  StringInfo
573    *plaintext;
574
575  /*
576    Decipher in ECB mode.
577  */
578  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
579  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
580  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
581  blocksize=cipher_info->blocksize;
582  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
583  WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
584  plaintext=ciphertext;
585  q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
586  for (p=GetStringInfoDatum(ciphertext); p < q; p+=blocksize)
587    cipher_info->decipher_block(cipher_info->handle,p,p);
588  return(plaintext);
589}
590
591/*
592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593%                                                                             %
594%                                                                             %
595%                                                                             %
596+   D e c i p h e r O F B M o d e                                             %
597%                                                                             %
598%                                                                             %
599%                                                                             %
600%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601%
602%  DecipherOFBMode() deciphers with the cipher in Output Feedback mode.  This
603%  mode is a confidentiality mode that features the iteration of the forward
604%  cipher on a nonce to generate a sequence of output blocks that are
605%  exclusive-ORed with the plaintext to produce the ciphertext, and vice versa.
606%  The OFB mode requires that the IV is a nonce, i.e., the IV must be unique
607%  for each execution of the mode under the given key.
608%
609%  The format of the DecipherOFBMode method is:
610%
611%     StringInfo *DecipherOFBMode(CipherInfo *cipher_info,
612%       StringInfo *ciphertext)
613%
614%  A description of each parameter follows:
615%
616%    o cipher_info: The cipher context.
617%
618%    o ciphertext: The cipher text.
619%
620*/
621static StringInfo *DecipherOFBMode(CipherInfo *cipher_info,
622  StringInfo *ciphertext)
623{
624  register size_t
625    i;
626
627  register unsigned char
628    *p,
629    *q;
630
631  size_t
632    blocksize;
633
634  StringInfo
635    *plaintext;
636
637  unsigned char
638    input_block[MaxCipherBlocksize];
639
640  /*
641    Decipher in OFB mode.
642  */
643  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
644  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
645  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
646  blocksize=cipher_info->blocksize;
647  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
648  WizardAssert(CipherDomain,ciphertext != (StringInfo *) NULL);
649  plaintext=ciphertext;
650  p=GetStringInfoDatum(cipher_info->nonce);
651  for (i=0; i < blocksize; i++)
652    input_block[i]=p[i];
653  q=GetStringInfoDatum(ciphertext)+GetStringInfoLength(ciphertext);
654  for (p=GetStringInfoDatum(ciphertext); p < q; p+=blocksize)
655  {
656    cipher_info->encipher_block(cipher_info->handle,input_block,input_block);
657    for (i=0; i < blocksize; i++)
658      p[i]^=input_block[i];
659  }
660  /*
661    Reset registers.
662  */
663  (void) ResetWizardMemory(input_block,0,sizeof(input_block));
664  return(plaintext);
665}
666
667/*
668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
669%                                                                             %
670%                                                                             %
671%                                                                             %
672%   D e s t r o y C i p h e r I n f o                                         %
673%                                                                             %
674%                                                                             %
675%                                                                             %
676%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
677%
678%  DestroyCipherInfo() zeros memory associated with the CipherInfo structure.
679%
680%  The format of the DestroyCipherInfo method is:
681%
682%      CipherInfo *DestroyCipherInfo(CipherInfo *cipher_info)
683%
684%  A description of each parameter follows:
685%
686%    o cipher_info: The cipher info.
687%
688*/
689WizardExport CipherInfo *DestroyCipherInfo(CipherInfo *cipher_info)
690{
691  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
692  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
693  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
694  if (cipher_info->handle != (CipherInfo *) NULL)
695    switch (cipher_info->cipher)
696    {
697      case AESCipher:
698      {
699        cipher_info->handle=DestroyAESInfo((AESInfo *) cipher_info->handle);
700        break;
701      }
702      case SerpentCipher:
703      {
704        cipher_info->handle=DestroySerpentInfo((SerpentInfo *)
705          cipher_info->handle);
706        break;
707      }
708      case TwofishCipher:
709      {
710        cipher_info->handle=DestroyTwofishInfo((TwofishInfo *)
711          cipher_info->handle);
712        break;
713      }
714      default:
715        ThrowWizardFatalError(CipherDomain,EnumerateError);
716    }
717  if (cipher_info->nonce != (StringInfo *) NULL)
718    cipher_info->nonce=DestroyStringInfo(cipher_info->nonce);
719  if (cipher_info->random_info != (RandomInfo *) NULL)
720    cipher_info->random_info=DestroyRandomInfo(cipher_info->random_info);
721  cipher_info->signature=(~WizardSignature);
722  cipher_info=(CipherInfo *) RelinquishWizardMemory(cipher_info);
723  return(cipher_info);
724}
725
726/*
727%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
728%                                                                             %
729%                                                                             %
730%                                                                             %
731+   E n c i p h e r C B C M o d e                                             %
732%                                                                             %
733%                                                                             %
734%                                                                             %
735%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736%
737%  EncipherCBCMode() enciphers with the cipher in Cipher Block Chaining mode.
738%  This mode is a confidentiality mode whose enciphering process features the
739%  combining ("chaining") of the plaintext blocks with the previous ciphertext
740%  blocks.  The CBC mode requires an IV to combine with the first plaintext
741%  block. The IV need not be secret, but it must be unpredictable.
742%
743%  The format of the EncipherCBCMode method is:
744%
745%      StringInfo *EncipherCBCMode(CipherInfo *cipher_info,
746%        StringInfo *plaintext)
747%
748%  A description of each parameter follows:
749%
750%    o cipher_info: The cipher context.
751%
752%    o plaintext: The plain text.
753%
754*/
755static StringInfo *EncipherCBCMode(CipherInfo *cipher_info,
756  StringInfo *plaintext)
757{
758  register unsigned char
759    *p,
760    *q;
761
762  register size_t
763    i;
764
765  size_t
766    blocksize,
767    pad;
768
769  StringInfo
770    *ciphertext;
771
772  unsigned char
773    input_block[MaxCipherBlocksize];
774
775  /*
776    Encipher in CBC mode.
777  */
778  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
779  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
780  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
781  blocksize=cipher_info->blocksize;
782  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
783  WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
784  ciphertext=plaintext;
785  p=GetStringInfoDatum(cipher_info->nonce);
786  for (i=0; i < blocksize; i++)
787    input_block[i]=p[i];
788  q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
789  pad=blocksize-GetStringInfoLength(plaintext) % blocksize;
790  SetRandomKey(cipher_info->random_info,pad-1,q);
791  q[pad-1]=(unsigned char) (pad-1);
792  if (pad == blocksize)
793    q+=blocksize;
794  for (p=GetStringInfoDatum(plaintext); p < q; p+=blocksize)
795  {
796    for (i=0; i < blocksize; i++)
797      p[i]^=input_block[i];
798    cipher_info->encipher_block(cipher_info->handle,p,p);
799    for (i=0; i < blocksize; i++)
800      input_block[i]=p[i];
801  }
802  /*
803    Reset registers.
804  */
805  (void) ResetWizardMemory(input_block,0,sizeof(input_block));
806  return(ciphertext);
807}
808
809/*
810%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
811%                                                                             %
812%                                                                             %
813%                                                                             %
814+   E n c i p h e r C F B M o d e                                             %
815%                                                                             %
816%                                                                             %
817%                                                                             %
818%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
819%
820%  EncipherCFBMode() enciphers with the cipher in Cipher Feedback mode.  This
821%  mode is a confidentiality mode that features the feedback of successive
822%  ciphertext segments into the input blocks of the forward cipher to generate
823%  output blocks that are exclusive-ORed with the plaintext to produce the
824%  ciphertext, and vice versa. The CFB mode requires a nonce as the initial
825%  input block. The nonce need not be secret, but it must be unpredictable.
826%
827%  The format of the EncipherCFBMode method is:
828%
829%      StringInfo *EncipherCFBMode(CipherInfo *cipher_info,
830%        StringInfo *plaintext)
831%
832%  A description of each parameter follows:
833%
834%    o cipher_info: The cipher context.
835%
836%    o plaintext: The plain text.
837%
838*/
839static StringInfo *EncipherCFBMode(CipherInfo *cipher_info,
840  StringInfo *plaintext)
841{
842  register size_t
843    i;
844
845  register unsigned char
846    *p,
847    *q;
848
849  size_t
850    blocksize;
851
852  StringInfo
853    *ciphertext;
854
855  unsigned char
856    input_block[MaxCipherBlocksize],
857    output_block[MaxCipherBlocksize];
858
859  /*
860    Encipher in CFB mode.
861  */
862  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
863  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
864  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
865  blocksize=cipher_info->blocksize;
866  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
867  WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
868  ciphertext=plaintext;
869  p=GetStringInfoDatum(cipher_info->nonce);
870  for (i=0; i < blocksize; i++)
871    input_block[i]=p[i];
872  q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
873  for (p=GetStringInfoDatum(plaintext); p < q; p++)
874  {
875    for (i=0; i < blocksize; i++)
876      output_block[i]=input_block[i];
877    cipher_info->encipher_block(cipher_info->handle,output_block,output_block);
878    *p^=(*output_block);
879    for (i=0; i < (blocksize-1); i++)
880      input_block[i]=input_block[i+1];
881    input_block[blocksize-1]=(*p);
882  }
883  /*
884    Reset registers.
885  */
886  (void) ResetWizardMemory(input_block,0,sizeof(input_block));
887  (void) ResetWizardMemory(output_block,0,sizeof(output_block));
888  return(ciphertext);
889}
890
891/*
892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893%                                                                             %
894%                                                                             %
895%                                                                             %
896%   E n c i p h e r C i p h e r                                               %
897%                                                                             %
898%                                                                             %
899%                                                                             %
900%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901%
902%  EncipherCipher() enciphers plaintext and returns ciphertext.  The
903%  enciphering is performed in-place and EncipherCipher() returns a pointer to
904%  the plaintext string.
905%
906%  The format of the EncipherCipher method is:
907%
908%     StringInfo *EncipherCipher(CipherInfo *cipher_info,StringInfo *plaintext)
909%
910%  A description of each parameter follows:
911%
912%    o cipher_info: The cipher context.
913%
914%    o plaintext: The plain text.
915%
916*/
917
918WizardExport StringInfo *EncryptCipher(CipherInfo *cipher_info,
919  StringInfo *plaintext)
920{
921  return(EncipherCipher(cipher_info,plaintext));
922}
923
924WizardExport StringInfo *EncipherCipher(CipherInfo *cipher_info,
925  StringInfo *plaintext)
926{
927  StringInfo
928    *ciphertext;
929
930  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
931  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
932  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
933  WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
934  ciphertext=(StringInfo *) NULL;
935  switch (cipher_info->mode)
936  {
937    case CBCMode:
938    {
939      ciphertext=EncipherCBCMode(cipher_info,plaintext);
940      break;
941    }
942    case CFBMode:
943    {
944      ciphertext=EncipherCFBMode(cipher_info,plaintext);
945      break;
946    }
947    case CTRMode:
948    {
949      ciphertext=EncipherCTRMode(cipher_info,plaintext);
950      break;
951    }
952    case ECBMode:
953    {
954      ciphertext=EncipherECBMode(cipher_info,plaintext);
955      break;
956    }
957    case OFBMode:
958    {
959      ciphertext=EncipherOFBMode(cipher_info,plaintext);
960      break;
961    }
962    default:
963      ThrowWizardFatalError(CipherDomain,EnumerateError);
964  }
965  return(ciphertext);
966}
967
968/*
969%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
970%                                                                             %
971%                                                                             %
972%                                                                             %
973+   E n c i p h e r C T R M o d e                                             %
974%                                                                             %
975%                                                                             %
976%                                                                             %
977%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978%
979%  EncipherCTRMode() enciphers with the cipher in Counter mode.  This mode is a
980%  confidentiality mode that features the application of the forward cipher to
981%  a set of input blocks, called counters, to produce a sequence of output
982%  blocks that are exclusive-ORed with the plaintext to produce the ciphertext,
983%  and vice versa. The sequence of counters must have the property that each
984%  block in the sequence is different from every other block. This condition is
985%  not restricted to a single message: across all of the messages that are
986%  enciphered under the given key, all of the counters must be distinct.
987%
988%  The format of the EncipherCTRMode method is:
989%
990%      StringInfo *EncipherCTRMode(CipherInfo *cipher_info,
991%        StringInfo *plaintext)
992%
993%  A description of each parameter follows:
994%
995%    o cipher_info: The cipher context.
996%
997%    o plaintext: The plain text.
998%
999*/
1000static StringInfo *EncipherCTRMode(CipherInfo *cipher_info,
1001  StringInfo *plaintext)
1002{
1003  register size_t
1004    i;
1005
1006  register unsigned char
1007    *p,
1008    *q;
1009
1010  size_t
1011    blocksize,
1012    pad;
1013
1014  StringInfo
1015    *ciphertext;
1016
1017  unsigned char
1018    input_block[MaxCipherBlocksize],
1019    output_block[MaxCipherBlocksize];
1020
1021  /*
1022    Encipher in CTR mode.
1023  */
1024  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
1025  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
1026  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
1027  blocksize=cipher_info->blocksize;
1028  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
1029  WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
1030  ciphertext=plaintext;
1031  p=GetStringInfoDatum(cipher_info->nonce);
1032  for (i=0; i < blocksize; i++)
1033    input_block[i]=p[i];
1034  q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
1035  pad=blocksize-GetStringInfoLength(plaintext) % blocksize;
1036  SetRandomKey(cipher_info->random_info,pad-1,q);
1037  q[pad-1]=(unsigned char) (pad-1);
1038  if (pad == blocksize)
1039    q+=blocksize;
1040  for (p=GetStringInfoDatum(plaintext); p < q; p+=blocksize)
1041  {
1042    for (i=0; i < blocksize; i++)
1043      output_block[i]=input_block[i];
1044    cipher_info->encipher_block(cipher_info->handle,output_block,output_block);
1045    for (i=0; i < blocksize; i++)
1046      p[i]^=output_block[i];
1047    IncrementCipherNonce(blocksize,input_block);
1048  }
1049  /*
1050    Reset registers.
1051  */
1052  (void) ResetWizardMemory(input_block,0,sizeof(input_block));
1053  (void) ResetWizardMemory(output_block,0,sizeof(output_block));
1054  return(ciphertext);
1055}
1056
1057/*
1058%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1059%                                                                             %
1060%                                                                             %
1061%                                                                             %
1062+   E n c i p h e r E C B M o d e                                             %
1063%                                                                             %
1064%                                                                             %
1065%                                                                             %
1066%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1067%
1068%  EncipherECBMode() enciphers with the cipher in Electronic Codebook mode.
1069%  This mode is a confidentiality mode that features, for a given key, the
1070%  assignment of a fixed ciphertext block to each plaintext block, analogous to
1071%  the assignment of code words in a codebook.
1072%
1073%  The format of the EncipherECBMode method is:
1074%
1075%      StringInfo *EncipherECBMode(CipherInfo *cipher_info,
1076%        StringInfo *plaintext)
1077%
1078%  A description of each parameter follows:
1079%
1080%    o cipher_info: The cipher context.
1081%
1082%    o plaintext: The plain text.
1083%
1084*/
1085static StringInfo *EncipherECBMode(CipherInfo *cipher_info,
1086  StringInfo *plaintext)
1087{
1088  register unsigned char
1089    *p,
1090    *q;
1091
1092  size_t
1093    blocksize,
1094    pad;
1095
1096  StringInfo
1097    *ciphertext;
1098
1099  /*
1100    Encipher in ECB mode.
1101  */
1102  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
1103  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
1104  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
1105  blocksize=cipher_info->blocksize;
1106  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
1107  WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
1108  ciphertext=plaintext;
1109  q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
1110  pad=blocksize-GetStringInfoLength(plaintext) % blocksize;
1111  SetRandomKey(cipher_info->random_info,pad-1,q);
1112  q[pad-1]=(unsigned char) (pad-1);
1113  if (pad == blocksize)
1114    q+=blocksize;
1115  for (p=GetStringInfoDatum(plaintext); p < q; p+=blocksize)
1116    cipher_info->encipher_block(cipher_info->handle,p,p);
1117  return(ciphertext);
1118}
1119
1120/*
1121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1122%                                                                             %
1123%                                                                             %
1124%                                                                             %
1125+   E n c i p h e r O F B M o d e                                             %
1126%                                                                             %
1127%                                                                             %
1128%                                                                             %
1129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1130%
1131%  EncipherOFBMode() enciphers with the cipher in Output Feedback mode.  This
1132%  mode is a confidentiality mode that features the iteration of the forward
1133%  cipher on a nonce to generate a sequence of output blocks that are
1134%  exclusive-ORed with the plaintext to produce the ciphertext, and vice versa.
1135%  The OFB mode requires that the IV is a nonce, i.e., the IV must be unique
1136%  for each execution of the mode under the given key.
1137%
1138%  The format of the EncipherOFBMode method is:
1139%
1140%      StringInfo *EncipherOFBMode(CipherInfo *cipher_info,
1141%        StringInfo *plaintext)
1142%
1143%  A description of each parameter follows:
1144%
1145%    o cipher_info: The cipher context.
1146%
1147%    o plaintext: The plain text.
1148%
1149*/
1150static StringInfo *EncipherOFBMode(CipherInfo *cipher_info,
1151  StringInfo *plaintext)
1152{
1153  register size_t
1154    i;
1155
1156  register unsigned char
1157    *p,
1158    *q;
1159
1160  size_t
1161    blocksize,
1162    pad;
1163
1164  StringInfo
1165    *ciphertext;
1166
1167  unsigned char
1168    input_block[MaxCipherBlocksize];
1169
1170  /*
1171    Encipher in OBC mode.
1172  */
1173  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
1174  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
1175  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
1176  blocksize=cipher_info->blocksize;
1177  WizardAssert(CipherDomain,blocksize <= MaxCipherBlocksize);
1178  WizardAssert(CipherDomain,plaintext != (StringInfo *) NULL);
1179  ciphertext=plaintext;
1180  p=GetStringInfoDatum(cipher_info->nonce);
1181  for (i=0; i < blocksize; i++)
1182    input_block[i]=p[i];
1183  q=GetStringInfoDatum(plaintext)+GetStringInfoLength(plaintext);
1184  pad=blocksize-GetStringInfoLength(plaintext) % blocksize;
1185  SetRandomKey(cipher_info->random_info,pad-1,q);
1186  q[pad-1]=(unsigned char) (pad-1);
1187  if (pad == blocksize)
1188    q+=blocksize;
1189  for (p=GetStringInfoDatum(plaintext); p < q; p+=blocksize)
1190  {
1191    cipher_info->encipher_block(cipher_info->handle,input_block,input_block);
1192    for (i=0; i < blocksize; i++)
1193      p[i]^=input_block[i];
1194  }
1195  /*
1196    Reset registers.
1197  */
1198  (void) ResetWizardMemory(input_block,0,sizeof(input_block));
1199  return(ciphertext);
1200}
1201
1202/*
1203%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1204%                                                                             %
1205%                                                                             %
1206%                                                                             %
1207%   G e t C i p h e r B l o c k s i z e                                       %
1208%                                                                             %
1209%                                                                             %
1210%                                                                             %
1211%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1212%
1213%  GetCipherBlocksize() returns the cipher blocksize.
1214%
1215%  The format of the GetCipherBlocksize method is:
1216%
1217%      size_t GetCipherBlocksize(const CipherInfo *cipher_info)
1218%
1219%  A description of each parameter follows:
1220%
1221%    o cipher_info: The cipher info.
1222%
1223*/
1224WizardExport size_t GetCipherBlocksize(const CipherInfo *cipher_info)
1225{
1226  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
1227  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
1228  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
1229  return(cipher_info->blocksize);
1230}
1231
1232/*
1233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1234%                                                                             %
1235%                                                                             %
1236%                                                                             %
1237%   G e n e r a t e C i p h e r N o n c e                                     %
1238%                                                                             %
1239%                                                                             %
1240%                                                                             %
1241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1242%
1243%  GenerateCipherNonce() generate a nonce for the given cipher.
1244%
1245%  The format of the GenerateCipherNonce method is:
1246%
1247%     StringInfo *GenerateCipherNonce(CipherInfo *cipher_info)
1248%
1249%  A description of each parameter follows:
1250%
1251%    o cipher_info: The cipher context.
1252%
1253*/
1254WizardExport StringInfo *GenerateCipherNonce(CipherInfo *cipher_info)
1255{
1256  StringInfo
1257    *nonce;
1258
1259  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
1260  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
1261  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
1262  switch (cipher_info->mode)
1263  {
1264    case CBCMode:
1265    case CFBMode:
1266    case ECBMode:
1267    case OFBMode:
1268    {
1269      nonce=GetRandomKey(cipher_info->random_info,cipher_info->blocksize);
1270      break;
1271    }
1272    case CTRMode:
1273    {
1274      nonce=AcquireStringInfo(cipher_info->blocksize);
1275      ResetStringInfo(nonce);
1276      SetRandomKey(cipher_info->random_info,(cipher_info->blocksize+1)/2,
1277        GetStringInfoDatum(nonce));
1278      break;
1279    }
1280    default:
1281      ThrowWizardFatalError(CipherDomain,EnumerateError);
1282  }
1283  return(nonce);
1284}
1285
1286/*
1287%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1288%                                                                             %
1289%                                                                             %
1290%                                                                             %
1291%   G e t C i p h e r N o n c e                                               %
1292%                                                                             %
1293%                                                                             %
1294%                                                                             %
1295%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296%
1297%  GetCipherNonce() returns a nonce of the cipher.
1298%
1299%  The format of the GetCipherNonce method is:
1300%
1301%     const StringInfo *GetCipherNonce(CipherInfo *cipher_info)
1302%
1303%  A description of each parameter follows:
1304%
1305%    o cipher_info: The cipher context.
1306%
1307*/
1308WizardExport const StringInfo *GetCipherNonce(CipherInfo *cipher_info)
1309{
1310  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
1311  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
1312  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
1313  return(cipher_info->nonce);
1314}
1315
1316/*
1317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318%                                                                             %
1319%                                                                             %
1320%                                                                             %
1321%   R e s e t C i p h e r N o n c e                                           %
1322%                                                                             %
1323%                                                                             %
1324%                                                                             %
1325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326%
1327%  ResetCipherNonce() resets the initialization vector for the cipher.
1328%
1329%  The format of the ResetCipherNonce method is:
1330%
1331%      ResetCipherNonce(CipherInfo *cipher_info)
1332%
1333%  A description of each parameter follows:
1334%
1335%    o cipher_info: The cipher context.
1336%
1337*/
1338WizardExport void ResetCipherNonce(CipherInfo *cipher_info)
1339{
1340  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
1341  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
1342  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
1343  ResetStringInfo(cipher_info->nonce);
1344}
1345
1346/*
1347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1348%                                                                             %
1349%                                                                             %
1350%                                                                             %
1351%   S e t C i p h e r N o n c e                                               %
1352%                                                                             %
1353%                                                                             %
1354%                                                                             %
1355%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1356%
1357%  SetCipherNonce() sets the initialization vector for the cipher.
1358%
1359%  The format of the SetCipherNonce method is:
1360%
1361%      SetCipherNonce(CipherInfo *cipher_info,const StringInfo *nonce)
1362%
1363%  A description of each parameter follows:
1364%
1365%    o cipher_info: The cipher context.
1366%
1367%    o nonce: The initialization vector.
1368%
1369*/
1370WizardExport void SetCipherNonce(CipherInfo *cipher_info,
1371  const StringInfo *nonce)
1372{
1373  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
1374  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
1375  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
1376  WizardAssert(CipherDomain,nonce != (StringInfo *) NULL);
1377  SetStringInfo(cipher_info->nonce,nonce);
1378}
1379
1380/*
1381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1382%                                                                             %
1383%                                                                             %
1384%                                                                             %
1385%   S e t C i p h e r K e y                                                   %
1386%                                                                             %
1387%                                                                             %
1388%                                                                             %
1389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1390%
1391%  SetCipherKey() sets the key for the cipher.  The key length is specified
1392%  in bits.  Valid values are 128, 192, or 256.
1393%
1394%  The format of the SetCipherKey method is:
1395%
1396%      SetCipherKey(CipherInfo *cipher_info,const StringInfo *key)
1397%
1398%  A description of each parameter follows:
1399%
1400%    o cipher_info: The cipher context.
1401%
1402%    o key: The key.
1403%
1404*/
1405WizardExport void SetCipherKey(CipherInfo *cipher_info,const StringInfo *key)
1406{
1407  (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
1408  WizardAssert(CipherDomain,cipher_info != (CipherInfo *) NULL);
1409  WizardAssert(CipherDomain,cipher_info->signature == WizardSignature);
1410  WizardAssert(CipherDomain,key != (StringInfo *) NULL);
1411  switch (cipher_info->cipher)
1412  {
1413    case AESCipher:
1414    {
1415      SetAESKey((AESInfo *) cipher_info->handle,key);
1416      break;
1417    }
1418    case SerpentCipher:
1419    {
1420      SetSerpentKey((SerpentInfo *) cipher_info->handle,key);
1421      break;
1422    }
1423    case TwofishCipher:
1424    {
1425      SetTwofishKey((TwofishInfo *) cipher_info->handle,key);
1426      break;
1427    }
1428    default:
1429      ThrowWizardFatalError(CipherDomain,EnumerateError);
1430  }
1431}
Note: See TracBrowser for help on using the browser.