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