• 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_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  */
gcm_add_iv(gcm_state * gcm,const unsigned char * IV,unsigned long IVlen)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