Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/encauth/gcm/gcm_done.c
8799 views
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_done.c
12
GCM implementation, Terminate the stream, by Tom St Denis
13
*/
14
#include "tomcrypt.h"
15
16
#ifdef LTC_GCM_MODE
17
18
/**
19
Terminate a GCM stream
20
@param gcm The GCM state
21
@param tag [out] The destination for the MAC tag
22
@param taglen [in/out] The length of the MAC tag
23
@return CRYPT_OK on success
24
*/
25
int gcm_done(gcm_state *gcm,
26
unsigned char *tag, unsigned long *taglen)
27
{
28
unsigned long x;
29
int err;
30
31
LTC_ARGCHK(gcm != NULL);
32
LTC_ARGCHK(tag != NULL);
33
LTC_ARGCHK(taglen != NULL);
34
35
if (gcm->buflen > 16 || gcm->buflen < 0) {
36
return CRYPT_INVALID_ARG;
37
}
38
39
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
40
return err;
41
}
42
43
if (gcm->mode == LTC_GCM_MODE_IV) {
44
/* let's process the IV */
45
if ((err = gcm_add_aad(gcm, NULL, 0)) != CRYPT_OK) return err;
46
}
47
48
if (gcm->mode == LTC_GCM_MODE_AAD) {
49
/* let's process the AAD */
50
if ((err = gcm_process(gcm, NULL, 0, NULL, 0)) != CRYPT_OK) return err;
51
}
52
53
if (gcm->mode != LTC_GCM_MODE_TEXT) {
54
return CRYPT_INVALID_ARG;
55
}
56
57
/* handle remaining ciphertext */
58
if (gcm->buflen) {
59
gcm->pttotlen += gcm->buflen * CONST64(8);
60
gcm_mult_h(gcm, gcm->X);
61
}
62
63
/* length */
64
STORE64H(gcm->totlen, gcm->buf);
65
STORE64H(gcm->pttotlen, gcm->buf+8);
66
for (x = 0; x < 16; x++) {
67
gcm->X[x] ^= gcm->buf[x];
68
}
69
gcm_mult_h(gcm, gcm->X);
70
71
/* encrypt original counter */
72
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) {
73
return err;
74
}
75
for (x = 0; x < 16 && x < *taglen; x++) {
76
tag[x] = gcm->buf[x] ^ gcm->X[x];
77
}
78
*taglen = x;
79
80
cipher_descriptor[gcm->cipher].done(&gcm->K);
81
82
return CRYPT_OK;
83
}
84
85
#endif
86
87