1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 /**
5 @file gcm_add_aad.c
6 GCM implementation, Add AAD data to the stream, by Tom St Denis
7 */
8 #include "tomcrypt_private.h"
9
10 #ifdef LTC_GCM_MODE
11
12 /**
13 Add AAD to the GCM state
14 @param gcm The GCM state
15 @param adata The additional authentication data to add to the GCM state
16 @param adatalen The length of the AAD data.
17 @return CRYPT_OK on success
18 */
gcm_add_aad(gcm_state * gcm,const unsigned char * adata,unsigned long adatalen)19 int gcm_add_aad(gcm_state *gcm,
20 const unsigned char *adata, unsigned long adatalen)
21 {
22 unsigned long x;
23 int err;
24 #ifdef LTC_FAST
25 unsigned long y;
26 #endif
27
28 LTC_ARGCHK(gcm != NULL);
29 if (adatalen > 0) {
30 LTC_ARGCHK(adata != NULL);
31 }
32
33 if (gcm->buflen > 16 || gcm->buflen < 0) {
34 return CRYPT_INVALID_ARG;
35 }
36
37 if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
38 return err;
39 }
40
41 /* in IV mode? */
42 if (gcm->mode == LTC_GCM_MODE_IV) {
43 /* IV length must be > 0 */
44 if (gcm->buflen == 0 && gcm->totlen == 0) return CRYPT_ERROR;
45 /* let's process the IV */
46 if (gcm->ivmode || gcm->buflen != 12) {
47 for (x = 0; x < (unsigned long)gcm->buflen; x++) {
48 gcm->X[x] ^= gcm->buf[x];
49 }
50 if (gcm->buflen) {
51 gcm->totlen += gcm->buflen * CONST64(8);
52 gcm_mult_h(gcm, gcm->X);
53 }
54
55 /* mix in the length */
56 zeromem(gcm->buf, 8);
57 STORE64H(gcm->totlen, gcm->buf+8);
58 for (x = 0; x < 16; x++) {
59 gcm->X[x] ^= gcm->buf[x];
60 }
61 gcm_mult_h(gcm, gcm->X);
62
63 /* copy counter out */
64 XMEMCPY(gcm->Y, gcm->X, 16);
65 zeromem(gcm->X, 16);
66 } else {
67 XMEMCPY(gcm->Y, gcm->buf, 12);
68 gcm->Y[12] = 0;
69 gcm->Y[13] = 0;
70 gcm->Y[14] = 0;
71 gcm->Y[15] = 1;
72 }
73 XMEMCPY(gcm->Y_0, gcm->Y, 16);
74 zeromem(gcm->buf, 16);
75 gcm->buflen = 0;
76 gcm->totlen = 0;
77 gcm->mode = LTC_GCM_MODE_AAD;
78 }
79
80 if (gcm->mode != LTC_GCM_MODE_AAD || gcm->buflen >= 16) {
81 return CRYPT_INVALID_ARG;
82 }
83
84 x = 0;
85 #ifdef LTC_FAST
86 if (gcm->buflen == 0 && adatalen > 15) {
87 for (x = 0; x < (adatalen & ~15); x += 16) {
88 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
89 *(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&adata[x + y]));
90 }
91 gcm_mult_h(gcm, gcm->X);
92 gcm->totlen += 128;
93 }
94 adata += x;
95 }
96 #endif
97
98
99 /* start adding AAD data to the state */
100 for (; x < adatalen; x++) {
101 gcm->X[gcm->buflen++] ^= *adata++;
102
103 if (gcm->buflen == 16) {
104 /* GF mult it */
105 gcm_mult_h(gcm, gcm->X);
106 gcm->buflen = 0;
107 gcm->totlen += 128;
108 }
109 }
110
111 return CRYPT_OK;
112 }
113 #endif
114
115