comparison src/encauth/gcm/gcm_add_aad.c @ 192:9cc34777b479 libtomcrypt

propagate from branch 'au.asn.ucc.matt.ltc-orig' (head 9ba8f01f44320e9cb9f19881105ae84f84a43ea9) to branch 'au.asn.ucc.matt.dropbear.ltc' (head dbf51c569bc34956ad948e4cc87a0eeb2170b768)
author Matt Johnston <matt@ucc.asn.au>
date Sun, 08 May 2005 06:36:47 +0000
parents 1c15b283127b
children 39d5d58461d6
comparison
equal deleted inserted replaced
164:cd1143579f00 192:9cc34777b479
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, [email protected], http://libtomcrypt.org
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, y;
31 int err;
32
33 LTC_ARGCHK(gcm != NULL);
34 if (adatalen > 0) {
35 LTC_ARGCHK(adata != NULL);
36 }
37
38 if (gcm->buflen > 16 || gcm->buflen < 0) {
39 return CRYPT_INVALID_ARG;
40 }
41
42 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
43 return err;
44 }
45
46 /* in IV mode? */
47 if (gcm->mode == GCM_MODE_IV) {
48 /* let's process the IV */
49 if (gcm->ivmode || gcm->buflen != 12) {
50 for (x = 0; x < (unsigned long)gcm->buflen; x++) {
51 gcm->X[x] ^= gcm->buf[x];
52 }
53 if (gcm->buflen) {
54 gcm->totlen += gcm->buflen * CONST64(8);
55 gcm_mult_h(gcm, gcm->X);
56 }
57
58 /* mix in the length */
59 zeromem(gcm->buf, 8);
60 STORE64H(gcm->totlen, gcm->buf+8);
61 for (x = 0; x < 16; x++) {
62 gcm->X[x] ^= gcm->buf[x];
63 }
64 gcm_mult_h(gcm, gcm->X);
65
66 /* copy counter out */
67 XMEMCPY(gcm->Y, gcm->X, 16);
68 zeromem(gcm->X, 16);
69 } else {
70 XMEMCPY(gcm->Y, gcm->buf, 12);
71 gcm->Y[12] = 0;
72 gcm->Y[13] = 0;
73 gcm->Y[14] = 0;
74 gcm->Y[15] = 1;
75 }
76 XMEMCPY(gcm->Y_0, gcm->Y, 16);
77 zeromem(gcm->buf, 16);
78 gcm->buflen = 0;
79 gcm->totlen = 0;
80 gcm->mode = GCM_MODE_AAD;
81 }
82
83 if (gcm->mode != GCM_MODE_AAD || gcm->buflen >= 16) {
84 return CRYPT_INVALID_ARG;
85 }
86
87 x = 0;
88 #ifdef LTC_FAST
89 if (gcm->buflen == 0) {
90 for (x = 0; x < (adatalen & ~15); x += 16) {
91 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
92 *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&adata[x + y]));
93 }
94 gcm_mult_h(gcm, gcm->X);
95 gcm->totlen += 128;
96 }
97 adata += x;
98 }
99 #endif
100
101
102 /* start adding AAD data to the state */
103 for (; x < adatalen; x++) {
104 gcm->X[gcm->buflen++] ^= *adata++;
105
106 if (gcm->buflen == 16) {
107 /* GF mult it */
108 gcm_mult_h(gcm, gcm->X);
109 gcm->buflen = 0;
110 gcm->totlen += 128;
111 }
112 }
113
114 return CRYPT_OK;
115 }
116 #endif
117