Home | History | Annotate | Download | only in pelican
      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