1/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10 */
11#include "tomcrypt.h"
12
13/**
14   @file ctr_start.c
15   CTR implementation, start chain, Tom St Denis
16*/
17
18
19#ifdef LTC_CTR_MODE
20
21/**
22   Initialize a CTR context
23   @param cipher      The index of the cipher desired
24   @param IV          The initial vector
25   @param key         The secret key
26   @param keylen      The length of the secret key (octets)
27   @param num_rounds  Number of rounds in the cipher desired (0 for default)
28   @param ctr_mode    The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN)
29   @param ctr         The CTR state to initialize
30   @return CRYPT_OK if successful
31*/
32int ctr_start(               int   cipher,
33              const unsigned char *IV,
34              const unsigned char *key,       int keylen,
35                             int  num_rounds, int ctr_mode,
36                   symmetric_CTR *ctr)
37{
38   int x, err;
39
40   LTC_ARGCHK(IV  != NULL);
41   LTC_ARGCHK(key != NULL);
42   LTC_ARGCHK(ctr != NULL);
43
44   /* bad param? */
45   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
46      return err;
47   }
48
49   /* setup cipher */
50   if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) {
51      return err;
52   }
53
54   /* copy ctr */
55   ctr->blocklen = cipher_descriptor[cipher].block_length;
56   ctr->cipher   = cipher;
57   ctr->padlen   = 0;
58   ctr->mode     = ctr_mode & 1;
59   for (x = 0; x < ctr->blocklen; x++) {
60       ctr->ctr[x] = IV[x];
61   }
62
63   if (ctr_mode & LTC_CTR_RFC3686) {
64      /* increment the IV as per RFC 3686 */
65      if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
66         /* little-endian */
67         for (x = 0; x < ctr->blocklen; x++) {
68             ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
69             if (ctr->ctr[x] != (unsigned char)0) {
70                break;
71             }
72         }
73      } else {
74         /* big-endian */
75         for (x = ctr->blocklen-1; x >= 0; x--) {
76             ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
77             if (ctr->ctr[x] != (unsigned char)0) {
78                break;
79             }
80         }
81      }
82   }
83
84   return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
85}
86
87#endif
88
89/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_start.c,v $ */
90/* $Revision: 1.11 $ */
91/* $Date: 2006/11/05 01:46:35 $ */
92