• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
20 static 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 */
ocb_init(ocb_state * ocb,int cipher,const unsigned char * key,unsigned long keylen,const unsigned char * nonce)47 int 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