Home | History | Annotate | Download | only in gcm
      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 
     12 /**
     13    @file gcm_add_iv.c
     14    GCM implementation, add IV data to the state, by Tom St Denis
     15 */
     16 #include "tomcrypt.h"
     17 
     18 #ifdef GCM_MODE
     19 
     20 /**
     21   Add IV data to the GCM state
     22   @param gcm    The GCM state
     23   @param IV     The initial value data to add
     24   @param IVlen  The length of the IV
     25   @return CRYPT_OK on success
     26  */
     27 int gcm_add_iv(gcm_state *gcm,
     28                const unsigned char *IV,     unsigned long IVlen)
     29 {
     30    unsigned long x, y;
     31    int           err;
     32 
     33    LTC_ARGCHK(gcm != NULL);
     34    if (IVlen > 0) {
     35       LTC_ARGCHK(IV  != NULL);
     36    }
     37 
     38    /* must be in IV mode */
     39    if (gcm->mode != GCM_MODE_IV) {
     40       return CRYPT_INVALID_ARG;
     41    }
     42 
     43    if (gcm->buflen >= 16 || gcm->buflen < 0) {
     44       return CRYPT_INVALID_ARG;
     45    }
     46 
     47    if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
     48       return err;
     49    }
     50 
     51 
     52    /* trip the ivmode flag */
     53    if (IVlen + gcm->buflen > 12) {
     54       gcm->ivmode |= 1;
     55    }
     56 
     57    x = 0;
     58 #ifdef LTC_FAST
     59    if (gcm->buflen == 0) {
     60       for (x = 0; x < (IVlen & ~15); x += 16) {
     61           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
     62               *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&IV[x + y]));
     63           }
     64           gcm_mult_h(gcm, gcm->X);
     65           gcm->totlen += 128;
     66       }
     67       IV += x;
     68    }
     69 #endif
     70 
     71    /* start adding IV data to the state */
     72    for (; x < IVlen; x++) {
     73        gcm->buf[gcm->buflen++] = *IV++;
     74 
     75        if (gcm->buflen == 16) {
     76          /* GF mult it */
     77          for (y = 0; y < 16; y++) {
     78              gcm->X[y] ^= gcm->buf[y];
     79          }
     80          gcm_mult_h(gcm, gcm->X);
     81          gcm->buflen = 0;
     82          gcm->totlen += 128;
     83       }
     84    }
     85 
     86    return CRYPT_OK;
     87 }
     88 
     89 #endif
     90 
     91 
     92 /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_add_iv.c,v $ */
     93 /* $Revision: 1.7 $ */
     94 /* $Date: 2006/03/31 14:15:35 $ */
     95