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, tomstdenis@gmail.com, http://libtomcrypt.com
10 */
11
12 /**
13 @file gcm_memory.c
14 GCM implementation, process a packet, by Tom St Denis
15 */
16 #include "tomcrypt.h"
17
18 #ifdef GCM_MODE
19
20 /**
21 Process an entire GCM packet in one call.
22 @param cipher Index of cipher to use
23 @param key The secret key
24 @param keylen The length of the secret key
25 @param IV The initial vector
26 @param IVlen The length of the initial vector
27 @param adata The additional authentication data (header)
28 @param adatalen The length of the adata
29 @param pt The plaintext
30 @param ptlen The length of the plaintext (ciphertext length is the same)
31 @param ct The ciphertext
32 @param tag [out] The MAC tag
33 @param taglen [in/out] The MAC tag length
34 @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
35 @return CRYPT_OK on success
36 */
gcm_memory(int cipher,const unsigned char * key,unsigned long keylen,const unsigned char * IV,unsigned long IVlen,const unsigned char * adata,unsigned long adatalen,unsigned char * pt,unsigned long ptlen,unsigned char * ct,unsigned char * tag,unsigned long * taglen,int direction)37 int gcm_memory( int cipher,
38 const unsigned char *key, unsigned long keylen,
39 const unsigned char *IV, unsigned long IVlen,
40 const unsigned char *adata, unsigned long adatalen,
41 unsigned char *pt, unsigned long ptlen,
42 unsigned char *ct,
43 unsigned char *tag, unsigned long *taglen,
44 int direction)
45 {
46 void *orig;
47 gcm_state *gcm;
48 int err;
49
50 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
51 return err;
52 }
53
54 if (cipher_descriptor[cipher].accel_gcm_memory != NULL) {
55 return
56 cipher_descriptor[cipher].accel_gcm_memory
57 (key, keylen,
58 IV, IVlen,
59 adata, adatalen,
60 pt, ptlen,
61 ct,
62 tag, taglen,
63 direction);
64 }
65
66
67
68 #ifndef GCM_TABLES_SSE2
69 orig = gcm = XMALLOC(sizeof(*gcm));
70 #else
71 orig = gcm = XMALLOC(sizeof(*gcm) + 16);
72 #endif
73 if (gcm == NULL) {
74 return CRYPT_MEM;
75 }
76
77 /* Force GCM to be on a multiple of 16 so we can use 128-bit aligned operations
78 * note that we only modify gcm and keep orig intact. This code is not portable
79 * but again it's only for SSE2 anyways, so who cares?
80 */
81 #ifdef GCM_TABLES_SSE2
82 if ((unsigned long)gcm & 15) {
83 gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15)));
84 }
85 #endif
86
87 if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) {
88 goto LTC_ERR;
89 }
90 if ((err = gcm_add_iv(gcm, IV, IVlen)) != CRYPT_OK) {
91 goto LTC_ERR;
92 }
93 if ((err = gcm_add_aad(gcm, adata, adatalen)) != CRYPT_OK) {
94 goto LTC_ERR;
95 }
96 if ((err = gcm_process(gcm, pt, ptlen, ct, direction)) != CRYPT_OK) {
97 goto LTC_ERR;
98 }
99 err = gcm_done(gcm, tag, taglen);
100 LTC_ERR:
101 XFREE(orig);
102 return err;
103 }
104 #endif
105
106
107 /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_memory.c,v $ */
108 /* $Revision: 1.23 $ */
109 /* $Date: 2006/09/07 10:00:57 $ */
110