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_done.c
     14    GCM implementation, Terminate the stream, by Tom St Denis
     15 */
     16 #include "tomcrypt.h"
     17 
     18 #ifdef GCM_MODE
     19 
     20 /**
     21   Terminate a GCM stream
     22   @param gcm     The GCM state
     23   @param tag     [out] The destination for the MAC tag
     24   @param taglen  [in/out]  The length of the MAC tag
     25   @return CRYPT_OK on success
     26  */
     27 int gcm_done(gcm_state *gcm,
     28                      unsigned char *tag,    unsigned long *taglen)
     29 {
     30    unsigned long x;
     31    int err;
     32 
     33    LTC_ARGCHK(gcm     != NULL);
     34    LTC_ARGCHK(tag     != NULL);
     35    LTC_ARGCHK(taglen  != NULL);
     36 
     37    if (gcm->buflen > 16 || gcm->buflen < 0) {
     38       return CRYPT_INVALID_ARG;
     39    }
     40 
     41    if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
     42       return err;
     43    }
     44 
     45 
     46    if (gcm->mode != GCM_MODE_TEXT) {
     47       return CRYPT_INVALID_ARG;
     48    }
     49 
     50    /* handle remaining ciphertext */
     51    if (gcm->buflen) {
     52       gcm->pttotlen += gcm->buflen * CONST64(8);
     53       gcm_mult_h(gcm, gcm->X);
     54    }
     55 
     56    /* length */
     57    STORE64H(gcm->totlen, gcm->buf);
     58    STORE64H(gcm->pttotlen, gcm->buf+8);
     59    for (x = 0; x < 16; x++) {
     60        gcm->X[x] ^= gcm->buf[x];
     61    }
     62    gcm_mult_h(gcm, gcm->X);
     63 
     64    /* encrypt original counter */
     65    if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) {
     66       return err;
     67    }
     68    for (x = 0; x < 16 && x < *taglen; x++) {
     69        tag[x] = gcm->buf[x] ^ gcm->X[x];
     70    }
     71    *taglen = x;
     72 
     73    cipher_descriptor[gcm->cipher].done(&gcm->K);
     74 
     75    return CRYPT_OK;
     76 }
     77 
     78 #endif
     79 
     80 
     81 /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_done.c,v $ */
     82 /* $Revision: 1.9 $ */
     83 /* $Date: 2006/03/31 14:15:35 $ */
     84