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 (at) gmail.com, http://libtomcrypt.com 10 */ 11 #include "tomcrypt.h" 12 13 /** 14 @file pmac_process.c 15 PMAC implementation, process data, by Tom St Denis 16 */ 17 18 19 #ifdef LTC_PMAC 20 21 /** 22 Process data in a PMAC stream 23 @param pmac The PMAC state 24 @param in The data to send through PMAC 25 @param inlen The length of the data to send through PMAC 26 @return CRYPT_OK if successful 27 */ 28 int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) 29 { 30 int err, n; 31 unsigned long x; 32 unsigned char Z[MAXBLOCKSIZE]; 33 34 LTC_ARGCHK(pmac != NULL); 35 LTC_ARGCHK(in != NULL); 36 if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) { 37 return err; 38 } 39 40 if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) || 41 (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) { 42 return CRYPT_INVALID_ARG; 43 } 44 45 #ifdef LTC_FAST 46 if (pmac->buflen == 0 && inlen > 16) { 47 unsigned long y; 48 for (x = 0; x < (inlen - 16); x += 16) { 49 pmac_shift_xor(pmac); 50 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { 51 *((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y])); 52 } 53 if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { 54 return err; 55 } 56 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { 57 *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y])); 58 } 59 in += 16; 60 } 61 inlen -= x; 62 } 63 #endif 64 65 while (inlen != 0) { 66 /* ok if the block is full we xor in prev, encrypt and replace prev */ 67 if (pmac->buflen == pmac->block_len) { 68 pmac_shift_xor(pmac); 69 for (x = 0; x < (unsigned long)pmac->block_len; x++) { 70 Z[x] = pmac->Li[x] ^ pmac->block[x]; 71 } 72 if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { 73 return err; 74 } 75 for (x = 0; x < (unsigned long)pmac->block_len; x++) { 76 pmac->checksum[x] ^= Z[x]; 77 } 78 pmac->buflen = 0; 79 } 80 81 /* add bytes */ 82 n = MIN(inlen, (unsigned long)(pmac->block_len - pmac->buflen)); 83 XMEMCPY(pmac->block + pmac->buflen, in, n); 84 pmac->buflen += n; 85 inlen -= n; 86 in += n; 87 } 88 89 #ifdef LTC_CLEAN_STACK 90 zeromem(Z, sizeof(Z)); 91 #endif 92 93 return CRYPT_OK; 94 } 95 96 #endif 97 98 /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_process.c,v $ */ 99 /* $Revision: 1.8 $ */ 100 /* $Date: 2006/11/03 00:39:49 $ */ 101