void (*gmult)(u64 Xi[2],const u128 Htable[16]);
void (*ghash)(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
#endif
- unsigned int res, pad;
+ unsigned int mres, ares;
block128_f block;
void *key;
};
ctx->Yi.u[1] = 0;
ctx->Xi.u[0] = 0;
ctx->Xi.u[1] = 0;
- ctx->len.u[0] = 0;
- ctx->len.u[1] = 0;
- ctx->res = 0;
+ ctx->len.u[0] = 0; /* AAD length */
+ ctx->len.u[1] = 0; /* message length */
+ ctx->ares = 0;
+ ctx->mres = 0;
if (len==12) {
memcpy(ctx->Yi.c,iv,12);
void CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx,const unsigned char *aad,size_t len)
{
size_t i;
+ int n;
ctx->len.u[0] += len;
+ n = ctx->ares;
+
+ if (n) {
+ while (n && len) {
+ ctx->Xi.c[n] ^= *(aad++);
+ --len;
+ n = (n+1)%16;
+ }
+ if (n==0) GCM_MUL(ctx,Xi);
+ else {
+ ctx->ares = n;
+ return;
+ }
+ }
#ifdef GHASH
if ((i = (len&(size_t)-16))) {
}
#endif
if (len) {
+ n = (int)len;
for (i=0; i<len; ++i) ctx->Xi.c[i] ^= aad[i];
- GCM_MUL(ctx,Xi);
}
+
+ ctx->ares = n;
}
void CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
unsigned int n, ctr;
size_t i;
+ if (ctx->ares) {
+ /* First call to encrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx,Xi);
+ ctx->ares = 0;
+ }
+
ctx->len.u[1] += len;
- n = ctx->res;
+ n = ctx->mres;
if (is_endian.little)
ctr = GETU32(ctx->Yi.c+12);
else
}
if (n==0) GCM_MUL(ctx,Xi);
else {
- ctx->res = n;
+ ctx->mres = n;
return;
}
}
}
}
- ctx->res = n;
+ ctx->mres = n;
return;
} while(0);
#endif
GCM_MUL(ctx,Xi);
}
- ctx->res = n;
+ ctx->mres = n;
}
void CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
unsigned int n, ctr;
size_t i;
+ if (ctx->ares) {
+ /* First call to decrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx,Xi);
+ ctx->ares = 0;
+ }
+
ctx->len.u[1] += len;
- n = ctx->res;
+ n = ctx->mres;
if (is_endian.little)
ctr = GETU32(ctx->Yi.c+12);
else
}
if (n==0) GCM_MUL (ctx,Xi);
else {
- ctx->res = n;
+ ctx->mres = n;
return;
}
}
}
}
- ctx->res = n;
+ ctx->mres = n;
return;
} while(0);
#endif
GCM_MUL(ctx,Xi);
}
- ctx->res = n;
+ ctx->mres = n;
}
void CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
unsigned int n, ctr;
size_t i;
+ if (ctx->ares) {
+ /* First call to encrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx,Xi);
+ ctx->ares = 0;
+ }
+
ctx->len.u[1] += len;
- n = ctx->res;
+ n = ctx->mres;
if (is_endian.little)
ctr = GETU32(ctx->Yi.c+12);
else
}
if (n==0) GCM_MUL(ctx,Xi);
else {
- ctx->res = n;
+ ctx->mres = n;
return;
}
}
}
}
- ctx->res = n;
+ ctx->mres = n;
}
void CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
unsigned int n, ctr;
size_t i;
+ if (ctx->ares) {
+ /* First call to decrypt finalizes GHASH(AAD) */
+ GCM_MUL(ctx,Xi);
+ ctx->ares = 0;
+ }
+
ctx->len.u[1] += len;
- n = ctx->res;
+ n = ctx->mres;
if (is_endian.little)
ctr = GETU32(ctx->Yi.c+12);
else
}
if (n==0) GCM_MUL (ctx,Xi);
else {
- ctx->res = n;
+ ctx->mres = n;
return;
}
}
}
}
- ctx->res = n;
+ ctx->mres = n;
}
int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
u64 alen = ctx->len.u[0]<<3;
u64 clen = ctx->len.u[1]<<3;
- if (ctx->res)
+ if (ctx->mres)
GCM_MUL(ctx,Xi);
if (is_endian.little) {
gcm_t = OPENSSL_rdtsc() - start;
CRYPTO_ctr128_encrypt(buf.c,buf.c,sizeof(buf),
- &key,ctx.Yi.c,ctx.EKi.c,&ctx.res,
+ &key,ctx.Yi.c,ctx.EKi.c,&ctx.mres,
(block128_f)AES_encrypt);
start = OPENSSL_rdtsc();
CRYPTO_ctr128_encrypt(buf.c,buf.c,sizeof(buf),
- &key,ctx.Yi.c,ctx.EKi.c,&ctx.res,
+ &key,ctx.Yi.c,ctx.EKi.c,&ctx.mres,
(block128_f)AES_encrypt);
ctr_t = OPENSSL_rdtsc() - start;