]> pd.if.org Git - zpackage/blob - libtomcrypt/src/mac/xcbc/xcbc_init.c
remove omac
[zpackage] / libtomcrypt / src / mac / xcbc / xcbc_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 #include "tomcrypt.h"
10
11 /**
12   @file xcbc_init.c
13   XCBC Support, start an XCBC state
14 */
15
16 #ifdef LTC_XCBC
17
18 /** Initialize XCBC-MAC state
19   @param xcbc    [out] XCBC state to initialize
20   @param cipher  Index of cipher to use
21   @param key     [in]  Secret key
22   @param keylen  Length of secret key in octets
23   Return CRYPT_OK on success
24 */
25 int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen)
26 {
27    int            x, y, err;
28    symmetric_key *skey;
29    unsigned long  k1;
30
31    LTC_ARGCHK(xcbc != NULL);
32    LTC_ARGCHK(key  != NULL);
33
34    /* schedule the key */
35    if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
36       return err;
37    }
38
39 #ifdef LTC_FAST
40    if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {
41        return CRYPT_INVALID_ARG;
42    }
43 #endif
44
45    skey = NULL;
46
47    /* are we in pure XCBC mode with three keys? */
48    if (keylen & LTC_XCBC_PURE) {
49       keylen &= ~LTC_XCBC_PURE;
50
51       if (keylen < 2UL*cipher_descriptor[cipher].block_length) {
52          return CRYPT_INVALID_ARG;
53       }
54
55       k1      = keylen - 2*cipher_descriptor[cipher].block_length;
56       XMEMCPY(xcbc->K[0], key, k1);
57       XMEMCPY(xcbc->K[1], key+k1, cipher_descriptor[cipher].block_length);
58       XMEMCPY(xcbc->K[2], key+k1 + cipher_descriptor[cipher].block_length, cipher_descriptor[cipher].block_length);
59    } else {
60       /* use the key expansion */
61       k1      = cipher_descriptor[cipher].block_length;
62
63       /* schedule the user key */
64       skey = XCALLOC(1, sizeof(*skey));
65       if (skey == NULL) {
66          return CRYPT_MEM;
67       }
68
69       if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
70          goto done;
71       }
72
73       /* make the three keys */
74       for (y = 0; y < 3; y++) {
75         for (x = 0; x < cipher_descriptor[cipher].block_length; x++) {
76            xcbc->K[y][x] = y + 1;
77         }
78         cipher_descriptor[cipher].ecb_encrypt(xcbc->K[y], xcbc->K[y], skey);
79       }
80    }
81
82    /* setup K1 */
83    err = cipher_descriptor[cipher].setup(xcbc->K[0], k1, 0, &xcbc->key);
84
85    /* setup struct */
86    zeromem(xcbc->IV, cipher_descriptor[cipher].block_length);
87    xcbc->blocksize = cipher_descriptor[cipher].block_length;
88    xcbc->cipher    = cipher;
89    xcbc->buflen    = 0;
90 done:
91    cipher_descriptor[cipher].done(skey);
92    if (skey != NULL) {
93 #ifdef LTC_CLEAN_STACK
94       zeromem(skey, sizeof(*skey));
95 #endif
96       XFREE(skey);
97    }
98    return err;
99 }
100
101 #endif
102
103 /* ref:         $Format:%D$ */
104 /* git commit:  $Format:%H$ */
105 /* commit time: $Format:%ai$ */
106