1
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
3
* LibTomCrypt is a library that provides various cryptographic
4
* algorithms in a highly modular and flexible manner.
6
* The library is free for all purposes without any express
9
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
14
GCM implementation, process message data, by Tom St Denis
21
Process plaintext/ciphertext through GCM
22
@param gcm The GCM state
23
@param pt The plaintext
24
@param ptlen The plaintext length (ciphertext length is the same)
25
@param ct The ciphertext
26
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
27
@return CRYPT_OK on success
29
int gcm_process(gcm_state *gcm,
30
unsigned char *pt, unsigned long ptlen,
38
LTC_ARGCHK(gcm != NULL);
40
LTC_ARGCHK(pt != NULL);
41
LTC_ARGCHK(ct != NULL);
44
if (gcm->buflen > 16 || gcm->buflen < 0) {
45
return CRYPT_INVALID_ARG;
48
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
53
if (gcm->mode == GCM_MODE_AAD) {
54
/* let's process the AAD */
56
gcm->totlen += gcm->buflen * CONST64(8);
57
gcm_mult_h(gcm, gcm->X);
60
/* increment counter */
61
for (y = 15; y >= 12; y--) {
62
if (++gcm->Y[y]) { break; }
64
/* encrypt the counter */
65
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
68
gcm->mode = GCM_MODE_TEXT;
71
if (gcm->mode != GCM_MODE_TEXT) {
72
return CRYPT_INVALID_ARG;
77
if (gcm->buflen == 0) {
78
if (direction == GCM_ENCRYPT) {
79
for (x = 0; x < (ptlen & ~15); x += 16) {
81
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
82
*((LTC_FAST_TYPE*)(&ct[x + y])) = *((LTC_FAST_TYPE*)(&pt[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y]));
83
*((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y]));
87
gcm_mult_h(gcm, gcm->X);
88
/* increment counter */
89
for (y = 15; y >= 12; y--) {
90
if (++gcm->Y[y]) { break; }
92
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
95
for (x = 0; x < (ptlen & ~15); x += 16) {
97
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
98
*((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y]));
99
*((LTC_FAST_TYPE*)(&pt[x + y])) = *((LTC_FAST_TYPE*)(&ct[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y]));
102
gcm->pttotlen += 128;
103
gcm_mult_h(gcm, gcm->X);
104
/* increment counter */
105
for (y = 15; y >= 12; y--) {
106
if (++gcm->Y[y]) { break; }
108
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
115
for (; x < ptlen; x++) {
116
if (gcm->buflen == 16) {
117
gcm->pttotlen += 128;
118
gcm_mult_h(gcm, gcm->X);
120
/* increment counter */
121
for (y = 15; y >= 12; y--) {
122
if (++gcm->Y[y]) { break; }
124
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
128
if (direction == GCM_ENCRYPT) {
129
b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen];
132
pt[x] = ct[x] ^ gcm->buf[gcm->buflen];
134
gcm->X[gcm->buflen++] ^= b;
145
/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_process.c,v $ */
146
/* $Revision: 1.8 $ */
147
/* $Date: 2005/05/05 14:35:58 $ */