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