mirror of
https://github.com/openssl/openssl.git
synced 2024-11-27 05:21:51 +08:00
gcm128.c: add CRYPTO_gcm128_[en|de]crypt_ctr32.
This commit is contained in:
parent
30ab7af242
commit
f71c6aceeb
@ -1092,6 +1092,171 @@ void CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
|
||||
ctx->res = n;
|
||||
}
|
||||
|
||||
void CRYPTO_gcm128_encrypt_crt32(GCM128_CONTEXT *ctx,
|
||||
const unsigned char *in, unsigned char *out,
|
||||
size_t len, ctr128_f stream)
|
||||
{
|
||||
const union { long one; char little; } is_endian = {1};
|
||||
unsigned int n, ctr;
|
||||
size_t i;
|
||||
|
||||
ctx->len.u[1] += len;
|
||||
n = ctx->res;
|
||||
if (is_endian.little)
|
||||
ctr = GETU32(ctx->Yi.c+12);
|
||||
else
|
||||
ctr = ctx->Yi.d[3];
|
||||
|
||||
if (n) {
|
||||
while (n && len) {
|
||||
ctx->Xi.c[n] ^= *(out++) = *(in++)^ctx->EKi.c[n];
|
||||
--len;
|
||||
n = (n+1)%16;
|
||||
}
|
||||
if (n==0) GCM_MUL(ctx,Xi);
|
||||
else {
|
||||
ctx->res = n;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
while (len>=GHASH_CHUNK) {
|
||||
(*stream)(in,out,GHASH_CHUNK/16,ctx->key,ctx->Yi.c);
|
||||
ctr += GHASH_CHUNK/16;
|
||||
if (is_endian.little)
|
||||
PUTU32(ctx->Yi.c+12,ctr);
|
||||
else
|
||||
ctx->Yi.d[3] = ctr;
|
||||
GHASH(ctx,out,GHASH_CHUNK);
|
||||
out += GHASH_CHUNK;
|
||||
in += GHASH_CHUNK;
|
||||
len -= GHASH_CHUNK;
|
||||
}
|
||||
#endif
|
||||
if ((i = (len&(size_t)-16))) {
|
||||
size_t j=i/16;
|
||||
|
||||
(*stream)(in,out,j,ctx->key,ctx->Yi.c);
|
||||
ctr += j;
|
||||
if (is_endian.little)
|
||||
PUTU32(ctx->Yi.c+12,ctr);
|
||||
else
|
||||
ctx->Yi.d[3] = ctr;
|
||||
in += i;
|
||||
len -= i;
|
||||
#if defined(GHASH)
|
||||
GHASH(ctx,out,i);
|
||||
out += i;
|
||||
#else
|
||||
while (j--) {
|
||||
for (i=0;i<16;++i) ctx->Xi.c[i] ^= out[i];
|
||||
GCM_MUL(ctx,Xi);
|
||||
out += 16;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (len) {
|
||||
(*ctx->block)(ctx->Yi.c,ctx->EKi.c,ctx->key);
|
||||
++ctr;
|
||||
if (is_endian.little)
|
||||
PUTU32(ctx->Yi.c+12,ctr);
|
||||
else
|
||||
ctx->Yi.d[3] = ctr;
|
||||
while (len--) {
|
||||
ctx->Xi.c[n] ^= out[n] = in[n]^ctx->EKi.c[n];
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->res = n;
|
||||
}
|
||||
|
||||
void CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
|
||||
const unsigned char *in, unsigned char *out,
|
||||
size_t len,ctr128_f stream)
|
||||
{
|
||||
const union { long one; char little; } is_endian = {1};
|
||||
unsigned int n, ctr;
|
||||
size_t i;
|
||||
|
||||
ctx->len.u[1] += len;
|
||||
n = ctx->res;
|
||||
if (is_endian.little)
|
||||
ctr = GETU32(ctx->Yi.c+12);
|
||||
else
|
||||
ctr = ctx->Yi.d[3];
|
||||
|
||||
if (n) {
|
||||
while (n && len) {
|
||||
u8 c = *(in++);
|
||||
*(out++) = c^ctx->EKi.c[n];
|
||||
ctx->Xi.c[n] ^= c;
|
||||
--len;
|
||||
n = (n+1)%16;
|
||||
}
|
||||
if (n==0) GCM_MUL (ctx,Xi);
|
||||
else {
|
||||
ctx->res = n;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
while (len>=GHASH_CHUNK) {
|
||||
GHASH(ctx,in,GHASH_CHUNK);
|
||||
(*stream)(in,out,GHASH_CHUNK/16,ctx->key,ctx->Yi.c);
|
||||
ctr += GHASH_CHUNK/16;
|
||||
if (is_endian.little)
|
||||
PUTU32(ctx->Yi.c+12,ctr);
|
||||
else
|
||||
ctx->Yi.d[3] = ctr;
|
||||
out += GHASH_CHUNK;
|
||||
in += GHASH_CHUNK;
|
||||
len -= GHASH_CHUNK;
|
||||
}
|
||||
#endif
|
||||
if ((i = (len&(size_t)-16))) {
|
||||
size_t j=i/16;
|
||||
|
||||
#if defined(GHASH)
|
||||
GHASH(ctx,in,i);
|
||||
#else
|
||||
while (j--) {
|
||||
size_t k;
|
||||
for (k=0;k<16;++k) ctx->Xi.c[k] ^= in[k];
|
||||
GCM_MUL(ctx,Xi);
|
||||
in += 16;
|
||||
}
|
||||
j = i/16;
|
||||
in -= i;
|
||||
#endif
|
||||
(*stream)(in,out,j,ctx->key,ctx->Yi.c);
|
||||
ctr += j;
|
||||
if (is_endian.little)
|
||||
PUTU32(ctx->Yi.c+12,ctr);
|
||||
else
|
||||
ctx->Yi.d[3] = ctr;
|
||||
out += i;
|
||||
in += i;
|
||||
len -= i;
|
||||
}
|
||||
if (len) {
|
||||
(*ctx->block)(ctx->Yi.c,ctx->EKi.c,ctx->key);
|
||||
++ctr;
|
||||
if (is_endian.little)
|
||||
PUTU32(ctx->Yi.c+12,ctr);
|
||||
else
|
||||
ctx->Yi.d[3] = ctr;
|
||||
while (len--) {
|
||||
u8 c = in[n];
|
||||
ctx->Xi.c[n] ^= c;
|
||||
out[n] = c^ctx->EKi.c[n];
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->res = n;
|
||||
}
|
||||
|
||||
int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
|
||||
size_t len)
|
||||
{
|
||||
|
@ -94,6 +94,12 @@ void CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
|
||||
void CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
|
||||
const unsigned char *in, unsigned char *out,
|
||||
size_t len);
|
||||
void CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
|
||||
const unsigned char *in, unsigned char *out,
|
||||
size_t len, ctr128_f stream);
|
||||
void CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
|
||||
const unsigned char *in, unsigned char *out,
|
||||
size_t len, ctr128_f stream);
|
||||
int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
|
||||
size_t len);
|
||||
void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user