• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@gmail.com, http://libtomcrypt.com
10  */
11 
12 /**
13    @file gcm_add_aad.c
14    GCM implementation, Add AAD data to the stream, by Tom St Denis
15 */
16 #include "tomcrypt.h"
17 
18 #ifdef GCM_MODE
19 
20 /**
21   Add AAD to the GCM state
22   @param gcm       The GCM state
23   @param adata     The additional authentication data to add to the GCM state
24   @param adatalen  The length of the AAD data.
25   @return CRYPT_OK on success
26  */
gcm_add_aad(gcm_state * gcm,const unsigned char * adata,unsigned long adatalen)27 int gcm_add_aad(gcm_state *gcm,
28                const unsigned char *adata,  unsigned long adatalen)
29 {
30    unsigned long x;
31    int           err;
32 #ifdef LTC_FAST
33    unsigned long y;
34 #endif
35 
36    LTC_ARGCHK(gcm    != NULL);
37    if (adatalen > 0) {
38       LTC_ARGCHK(adata  != NULL);
39    }
40 
41    if (gcm->buflen > 16 || gcm->buflen < 0) {
42       return CRYPT_INVALID_ARG;
43    }
44 
45    if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
46       return err;
47    }
48 
49    /* in IV mode? */
50    if (gcm->mode == GCM_MODE_IV) {
51       /* let's process the IV */
52       if (gcm->ivmode || gcm->buflen != 12) {
53          for (x = 0; x < (unsigned long)gcm->buflen; x++) {
54              gcm->X[x] ^= gcm->buf[x];
55          }
56          if (gcm->buflen) {
57             gcm->totlen += gcm->buflen * CONST64(8);
58             gcm_mult_h(gcm, gcm->X);
59          }
60 
61          /* mix in the length */
62          zeromem(gcm->buf, 8);
63          STORE64H(gcm->totlen, gcm->buf+8);
64          for (x = 0; x < 16; x++) {
65              gcm->X[x] ^= gcm->buf[x];
66          }
67          gcm_mult_h(gcm, gcm->X);
68 
69          /* copy counter out */
70          XMEMCPY(gcm->Y, gcm->X, 16);
71          zeromem(gcm->X, 16);
72       } else {
73          XMEMCPY(gcm->Y, gcm->buf, 12);
74          gcm->Y[12] = 0;
75          gcm->Y[13] = 0;
76          gcm->Y[14] = 0;
77          gcm->Y[15] = 1;
78       }
79       XMEMCPY(gcm->Y_0, gcm->Y, 16);
80       zeromem(gcm->buf, 16);
81       gcm->buflen = 0;
82       gcm->totlen = 0;
83       gcm->mode   = GCM_MODE_AAD;
84    }
85 
86    if (gcm->mode != GCM_MODE_AAD || gcm->buflen >= 16) {
87       return CRYPT_INVALID_ARG;
88    }
89 
90    x = 0;
91 #ifdef LTC_FAST
92    if (gcm->buflen == 0) {
93       for (x = 0; x < (adatalen & ~15); x += 16) {
94           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
95               *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&adata[x + y]));
96           }
97           gcm_mult_h(gcm, gcm->X);
98           gcm->totlen += 128;
99       }
100       adata += x;
101    }
102 #endif
103 
104 
105    /* start adding AAD data to the state */
106    for (; x < adatalen; x++) {
107        gcm->X[gcm->buflen++] ^= *adata++;
108 
109        if (gcm->buflen == 16) {
110          /* GF mult it */
111          gcm_mult_h(gcm, gcm->X);
112          gcm->buflen = 0;
113          gcm->totlen += 128;
114       }
115    }
116 
117    return CRYPT_OK;
118 }
119 #endif
120 
121 
122 /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_add_aad.c,v $ */
123 /* $Revision: 1.16 $ */
124 /* $Date: 2006/09/23 19:24:21 $ */
125