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 (at) 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 */ 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