Path: blob/master/libs/tomcrypt/src/encauth/gcm/gcm_add_aad.c
8795 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/89/**10@file gcm_add_aad.c11GCM implementation, Add AAD data to the stream, by Tom St Denis12*/13#include "tomcrypt.h"1415#ifdef LTC_GCM_MODE1617/**18Add AAD to the GCM state19@param gcm The GCM state20@param adata The additional authentication data to add to the GCM state21@param adatalen The length of the AAD data.22@return CRYPT_OK on success23*/24int gcm_add_aad(gcm_state *gcm,25const unsigned char *adata, unsigned long adatalen)26{27unsigned long x;28int err;29#ifdef LTC_FAST30unsigned long y;31#endif3233LTC_ARGCHK(gcm != NULL);34if (adatalen > 0) {35LTC_ARGCHK(adata != NULL);36}3738if (gcm->buflen > 16 || gcm->buflen < 0) {39return CRYPT_INVALID_ARG;40}4142if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {43return err;44}4546/* in IV mode? */47if (gcm->mode == LTC_GCM_MODE_IV) {48/* IV length must be > 0 */49if (gcm->buflen == 0 && gcm->totlen == 0) return CRYPT_ERROR;50/* let's process the IV */51if (gcm->ivmode || gcm->buflen != 12) {52for (x = 0; x < (unsigned long)gcm->buflen; x++) {53gcm->X[x] ^= gcm->buf[x];54}55if (gcm->buflen) {56gcm->totlen += gcm->buflen * CONST64(8);57gcm_mult_h(gcm, gcm->X);58}5960/* mix in the length */61zeromem(gcm->buf, 8);62STORE64H(gcm->totlen, gcm->buf+8);63for (x = 0; x < 16; x++) {64gcm->X[x] ^= gcm->buf[x];65}66gcm_mult_h(gcm, gcm->X);6768/* copy counter out */69XMEMCPY(gcm->Y, gcm->X, 16);70zeromem(gcm->X, 16);71} else {72XMEMCPY(gcm->Y, gcm->buf, 12);73gcm->Y[12] = 0;74gcm->Y[13] = 0;75gcm->Y[14] = 0;76gcm->Y[15] = 1;77}78XMEMCPY(gcm->Y_0, gcm->Y, 16);79zeromem(gcm->buf, 16);80gcm->buflen = 0;81gcm->totlen = 0;82gcm->mode = LTC_GCM_MODE_AAD;83}8485if (gcm->mode != LTC_GCM_MODE_AAD || gcm->buflen >= 16) {86return CRYPT_INVALID_ARG;87}8889x = 0;90#ifdef LTC_FAST91if (gcm->buflen == 0) {92for (x = 0; x < (adatalen & ~15); x += 16) {93for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {94*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&adata[x + y]));95}96gcm_mult_h(gcm, gcm->X);97gcm->totlen += 128;98}99adata += x;100}101#endif102103104/* start adding AAD data to the state */105for (; x < adatalen; x++) {106gcm->X[gcm->buflen++] ^= *adata++;107108if (gcm->buflen == 16) {109/* GF mult it */110gcm_mult_h(gcm, gcm->X);111gcm->buflen = 0;112gcm->totlen += 128;113}114}115116return CRYPT_OK;117}118#endif119120121