Path: blob/master/libs/tomcrypt/src/mac/pmac/pmac_init.c
8525 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 pmac_init.c12PMAC implementation, initialize state, by Tom St Denis13*/1415#ifdef LTC_PMAC1617static const struct {18int len;19unsigned char poly_div[MAXBLOCKSIZE],20poly_mul[MAXBLOCKSIZE];21} polys[] = {22{238,24{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },25{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }26}, {2716,28{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },30{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }32}33};3435/**36Initialize a PMAC state37@param pmac The PMAC state to initialize38@param cipher The index of the desired cipher39@param key The secret key40@param keylen The length of the secret key (octets)41@return CRYPT_OK if successful42*/43int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen)44{45int poly, x, y, m, err;46unsigned char *L;4748LTC_ARGCHK(pmac != NULL);49LTC_ARGCHK(key != NULL);5051/* valid cipher? */52if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {53return err;54}5556/* determine which polys to use */57pmac->block_len = cipher_descriptor[cipher].block_length;58for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) {59if (polys[poly].len == pmac->block_len) {60break;61}62}63if (poly >= (int)(sizeof(polys)/sizeof(polys[0]))) {64return CRYPT_INVALID_ARG;65}66if (polys[poly].len != pmac->block_len) {67return CRYPT_INVALID_ARG;68}6970#ifdef LTC_FAST71if (pmac->block_len % sizeof(LTC_FAST_TYPE)) {72return CRYPT_INVALID_ARG;73}74#endif757677/* schedule the key */78if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) {79return err;80}8182/* allocate L */83L = XMALLOC(pmac->block_len);84if (L == NULL) {85return CRYPT_MEM;86}8788/* find L = E[0] */89zeromem(L, pmac->block_len);90if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) {91goto error;92}9394/* find Ls[i] = L << i for i == 0..31 */95XMEMCPY(pmac->Ls[0], L, pmac->block_len);96for (x = 1; x < 32; x++) {97m = pmac->Ls[x-1][0] >> 7;98for (y = 0; y < pmac->block_len-1; y++) {99pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255;100}101pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255;102103if (m == 1) {104for (y = 0; y < pmac->block_len; y++) {105pmac->Ls[x][y] ^= polys[poly].poly_mul[y];106}107}108}109110/* find Lr = L / x */111m = L[pmac->block_len-1] & 1;112113/* shift right */114for (x = pmac->block_len - 1; x > 0; x--) {115pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255;116}117pmac->Lr[0] = L[0] >> 1;118119if (m == 1) {120for (x = 0; x < pmac->block_len; x++) {121pmac->Lr[x] ^= polys[poly].poly_div[x];122}123}124125/* zero buffer, counters, etc... */126pmac->block_index = 1;127pmac->cipher_idx = cipher;128pmac->buflen = 0;129zeromem(pmac->block, sizeof(pmac->block));130zeromem(pmac->Li, sizeof(pmac->Li));131zeromem(pmac->checksum, sizeof(pmac->checksum));132err = CRYPT_OK;133error:134#ifdef LTC_CLEAN_STACK135zeromem(L, pmac->block_len);136#endif137138XFREE(L);139140return err;141}142143#endif144145146