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_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 */ 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