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
12/**
13   @file ocb_init.c
14   OCB implementation, initialize state, by Tom St Denis
15*/
16#include "tomcrypt.h"
17
18#ifdef OCB_MODE
19
20static const struct {
21    int           len;
22    unsigned char poly_div[MAXBLOCKSIZE],
23                  poly_mul[MAXBLOCKSIZE];
24} polys[] = {
25{
26    8,
27    { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },
28    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
29}, {
30    16,
31    { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },
33    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
35}
36};
37
38/**
39  Initialize an OCB context.
40  @param ocb     [out] The destination of the OCB state
41  @param cipher  The index of the desired cipher
42  @param key     The secret key
43  @param keylen  The length of the secret key (octets)
44  @param nonce   The session nonce (length of the block size of the cipher)
45  @return CRYPT_OK if successful
46*/
47int ocb_init(ocb_state *ocb, int cipher,
48             const unsigned char *key, unsigned long keylen, const unsigned char *nonce)
49{
50   int poly, x, y, m, err;
51
52   LTC_ARGCHK(ocb   != NULL);
53   LTC_ARGCHK(key   != NULL);
54   LTC_ARGCHK(nonce != NULL);
55
56   /* valid cipher? */
57   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
58      return err;
59   }
60
61   /* determine which polys to use */
62   ocb->block_len = cipher_descriptor[cipher].block_length;
63   for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) {
64       if (polys[poly].len == ocb->block_len) {
65          break;
66       }
67   }
68   if (polys[poly].len != ocb->block_len) {
69      return CRYPT_INVALID_ARG;
70   }
71
72   /* schedule the key */
73   if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {
74      return err;
75   }
76
77   /* find L = E[0] */
78   zeromem(ocb->L, ocb->block_len);
79   if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) {
80      return err;
81   }
82
83   /* find R = E[N xor L] */
84   for (x = 0; x < ocb->block_len; x++) {
85       ocb->R[x] = ocb->L[x] ^ nonce[x];
86   }
87   if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) {
88      return err;
89   }
90
91   /* find Ls[i] = L << i for i == 0..31 */
92   XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len);
93   for (x = 1; x < 32; x++) {
94       m = ocb->Ls[x-1][0] >> 7;
95       for (y = 0; y < ocb->block_len-1; y++) {
96           ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255;
97       }
98       ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255;
99
100       if (m == 1) {
101          for (y = 0; y < ocb->block_len; y++) {
102              ocb->Ls[x][y] ^= polys[poly].poly_mul[y];
103          }
104       }
105    }
106
107    /* find Lr = L / x */
108    m = ocb->L[ocb->block_len-1] & 1;
109
110    /* shift right */
111    for (x = ocb->block_len - 1; x > 0; x--) {
112        ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255;
113    }
114    ocb->Lr[0] = ocb->L[0] >> 1;
115
116    if (m == 1) {
117       for (x = 0; x < ocb->block_len; x++) {
118           ocb->Lr[x] ^= polys[poly].poly_div[x];
119       }
120    }
121
122    /* set Li, checksum */
123    zeromem(ocb->Li,       ocb->block_len);
124    zeromem(ocb->checksum, ocb->block_len);
125
126    /* set other params */
127    ocb->block_index = 1;
128    ocb->cipher      = cipher;
129
130    return CRYPT_OK;
131}
132
133#endif
134
135/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_init.c,v $ */
136/* $Revision: 1.5 $ */
137/* $Date: 2006/03/31 14:15:35 $ */
138