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 pelican.c 15 Pelican MAC, initialize state, by Tom St Denis 16 */ 17 18 #ifdef PELICAN 19 20 #define ENCRYPT_ONLY 21 #define PELI_TAB 22 #include "../../ciphers/aes/aes_tab.c" 23 24 /** 25 Initialize a Pelican state 26 @param pelmac The Pelican state to initialize 27 @param key The secret key 28 @param keylen The length of the secret key (octets) 29 @return CRYPT_OK if successful 30 */ 31 int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen) 32 { 33 int err; 34 35 LTC_ARGCHK(pelmac != NULL); 36 LTC_ARGCHK(key != NULL); 37 38 #ifdef LTC_FAST 39 if (16 % sizeof(LTC_FAST_TYPE)) { 40 return CRYPT_INVALID_ARG; 41 } 42 #endif 43 44 if ((err = aes_setup(key, keylen, 0, &pelmac->K)) != CRYPT_OK) { 45 return err; 46 } 47 48 zeromem(pelmac->state, 16); 49 aes_ecb_encrypt(pelmac->state, pelmac->state, &pelmac->K); 50 pelmac->buflen = 0; 51 52 return CRYPT_OK; 53 } 54 55 static void four_rounds(pelican_state *pelmac) 56 { 57 ulong32 s0, s1, s2, s3, t0, t1, t2, t3; 58 int r; 59 60 LOAD32H(s0, pelmac->state ); 61 LOAD32H(s1, pelmac->state + 4); 62 LOAD32H(s2, pelmac->state + 8); 63 LOAD32H(s3, pelmac->state + 12); 64 for (r = 0; r < 4; r++) { 65 t0 = 66 Te0(byte(s0, 3)) ^ 67 Te1(byte(s1, 2)) ^ 68 Te2(byte(s2, 1)) ^ 69 Te3(byte(s3, 0)); 70 t1 = 71 Te0(byte(s1, 3)) ^ 72 Te1(byte(s2, 2)) ^ 73 Te2(byte(s3, 1)) ^ 74 Te3(byte(s0, 0)); 75 t2 = 76 Te0(byte(s2, 3)) ^ 77 Te1(byte(s3, 2)) ^ 78 Te2(byte(s0, 1)) ^ 79 Te3(byte(s1, 0)); 80 t3 = 81 Te0(byte(s3, 3)) ^ 82 Te1(byte(s0, 2)) ^ 83 Te2(byte(s1, 1)) ^ 84 Te3(byte(s2, 0)); 85 s0 = t0; s1 = t1; s2 = t2; s3 = t3; 86 } 87 STORE32H(s0, pelmac->state ); 88 STORE32H(s1, pelmac->state + 4); 89 STORE32H(s2, pelmac->state + 8); 90 STORE32H(s3, pelmac->state + 12); 91 } 92 93 /** 94 Process a block of text through Pelican 95 @param pelmac The Pelican MAC state 96 @param in The input 97 @param inlen The length input (octets) 98 @return CRYPT_OK on success 99 */ 100 int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen) 101 { 102 103 LTC_ARGCHK(pelmac != NULL); 104 LTC_ARGCHK(in != NULL); 105 106 /* check range */ 107 if (pelmac->buflen < 0 || pelmac->buflen > 15) { 108 return CRYPT_INVALID_ARG; 109 } 110 111 #ifdef LTC_FAST 112 if (pelmac->buflen == 0) { 113 while (inlen & ~15) { 114 int x; 115 for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { 116 *((LTC_FAST_TYPE*)((unsigned char *)pelmac->state + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)in + x)); 117 } 118 four_rounds(pelmac); 119 in += 16; 120 inlen -= 16; 121 } 122 } 123 #endif 124 125 while (inlen--) { 126 pelmac->state[pelmac->buflen++] ^= *in++; 127 if (pelmac->buflen == 16) { 128 four_rounds(pelmac); 129 pelmac->buflen = 0; 130 } 131 } 132 return CRYPT_OK; 133 } 134 135 /** 136 Terminate Pelican MAC 137 @param pelmac The Pelican MAC state 138 @param out [out] The TAG 139 @return CRYPT_OK on sucess 140 */ 141 int pelican_done(pelican_state *pelmac, unsigned char *out) 142 { 143 LTC_ARGCHK(pelmac != NULL); 144 LTC_ARGCHK(out != NULL); 145 146 /* check range */ 147 if (pelmac->buflen < 0 || pelmac->buflen > 16) { 148 return CRYPT_INVALID_ARG; 149 } 150 151 if (pelmac->buflen == 16) { 152 four_rounds(pelmac); 153 pelmac->buflen = 0; 154 } 155 pelmac->state[pelmac->buflen++] ^= 0x80; 156 aes_ecb_encrypt(pelmac->state, out, &pelmac->K); 157 aes_done(&pelmac->K); 158 return CRYPT_OK; 159 } 160 161 #endif 162 163 /* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican.c,v $ */ 164 /* $Revision: 1.18 $ */ 165 /* $Date: 2006/04/02 13:19:10 $ */ 166