comparison libtomcrypt/src/encauth/gcm/gcm_add_aad.c @ 285:1b9e69c058d2

propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 20dccfc09627970a312d77fb41dc2970b62689c3) to branch 'au.asn.ucc.matt.dropbear' (head fdf4a7a3b97ae5046139915de7e40399cceb2c01)
author Matt Johnston <matt@ucc.asn.au>
date Wed, 08 Mar 2006 13:23:58 +0000
parents
children 0cbe8f6dbf9e
comparison
equal deleted inserted replaced
281:997e6f7dc01e 285:1b9e69c058d2
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;
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.14 $ */
124 /* $Date: 2005/05/05 14:35:58 $ */