]> pd.if.org Git - zpackage/blob - libtomcrypt/src/encauth/gcm/gcm_add_iv.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / encauth / gcm / gcm_add_iv.c
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
10 /**
11    @file gcm_add_iv.c
12    GCM implementation, add IV data to the state, by Tom St Denis
13 */
14 #include "tomcrypt.h"
15
16 #ifdef LTC_GCM_MODE
17
18 /**
19   Add IV data to the GCM state
20   @param gcm    The GCM state
21   @param IV     The initial value data to add
22   @param IVlen  The length of the IV
23   @return CRYPT_OK on success
24  */
25 int gcm_add_iv(gcm_state *gcm,
26                const unsigned char *IV,     unsigned long IVlen)
27 {
28    unsigned long x, y;
29    int           err;
30
31    LTC_ARGCHK(gcm != NULL);
32    if (IVlen > 0) {
33       LTC_ARGCHK(IV  != NULL);
34    }
35
36    /* must be in IV mode */
37    if (gcm->mode != LTC_GCM_MODE_IV) {
38       return CRYPT_INVALID_ARG;
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
50    /* trip the ivmode flag */
51    if (IVlen + gcm->buflen > 12) {
52       gcm->ivmode |= 1;
53    }
54
55    x = 0;
56 #ifdef LTC_FAST
57    if (gcm->buflen == 0) {
58       for (x = 0; x < (IVlen & ~15); x += 16) {
59           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
60               *(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&IV[x + y]));
61           }
62           gcm_mult_h(gcm, gcm->X);
63           gcm->totlen += 128;
64       }
65       IV += x;
66    }
67 #endif
68
69    /* start adding IV data to the state */
70    for (; x < IVlen; x++) {
71        gcm->buf[gcm->buflen++] = *IV++;
72
73       if (gcm->buflen == 16) {
74          /* GF mult it */
75          for (y = 0; y < 16; y++) {
76              gcm->X[y] ^= gcm->buf[y];
77          }
78          gcm_mult_h(gcm, gcm->X);
79          gcm->buflen = 0;
80          gcm->totlen += 128;
81       }
82    }
83
84    return CRYPT_OK;
85 }
86
87 #endif
88
89
90 /* ref:         $Format:%D$ */
91 /* git commit:  $Format:%H$ */
92 /* commit time: $Format:%ai$ */