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