Path: blob/master/libs/tomcrypt/src/mac/xcbc/xcbc_init.c
5972 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/8#include "tomcrypt.h"910/**11@file xcbc_init.c12XCBC Support, start an XCBC state13*/1415#ifdef LTC_XCBC1617/** Initialize XCBC-MAC state18@param xcbc [out] XCBC state to initialize19@param cipher Index of cipher to use20@param key [in] Secret key21@param keylen Length of secret key in octets22Return CRYPT_OK on success23*/24int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen)25{26int x, y, err;27symmetric_key *skey;28unsigned long k1;2930LTC_ARGCHK(xcbc != NULL);31LTC_ARGCHK(key != NULL);3233/* schedule the key */34if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {35return err;36}3738#ifdef LTC_FAST39if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {40return CRYPT_INVALID_ARG;41}42#endif4344skey = NULL;4546/* are we in pure XCBC mode with three keys? */47if (keylen & LTC_XCBC_PURE) {48keylen &= ~LTC_XCBC_PURE;4950if (keylen < 2UL*cipher_descriptor[cipher].block_length) {51return CRYPT_INVALID_ARG;52}5354k1 = keylen - 2*cipher_descriptor[cipher].block_length;55XMEMCPY(xcbc->K[0], key, k1);56XMEMCPY(xcbc->K[1], key+k1, cipher_descriptor[cipher].block_length);57XMEMCPY(xcbc->K[2], key+k1 + cipher_descriptor[cipher].block_length, cipher_descriptor[cipher].block_length);58} else {59/* use the key expansion */60k1 = cipher_descriptor[cipher].block_length;6162/* schedule the user key */63skey = XCALLOC(1, sizeof(*skey));64if (skey == NULL) {65return CRYPT_MEM;66}6768if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {69goto done;70}7172/* make the three keys */73for (y = 0; y < 3; y++) {74for (x = 0; x < cipher_descriptor[cipher].block_length; x++) {75xcbc->K[y][x] = y + 1;76}77cipher_descriptor[cipher].ecb_encrypt(xcbc->K[y], xcbc->K[y], skey);78}79}8081/* setup K1 */82err = cipher_descriptor[cipher].setup(xcbc->K[0], k1, 0, &xcbc->key);8384/* setup struct */85zeromem(xcbc->IV, cipher_descriptor[cipher].block_length);86xcbc->blocksize = cipher_descriptor[cipher].block_length;87xcbc->cipher = cipher;88xcbc->buflen = 0;89done:90cipher_descriptor[cipher].done(skey);91if (skey != NULL) {92#ifdef LTC_CLEAN_STACK93zeromem(skey, sizeof(*skey));94#endif95XFREE(skey);96}97return err;98}99100#endif101102103