AES-CTR: improve performance when multiple blocks

When in and out aren't the same pointer, for multiples of block size
input:
  - generate the counters into the output buffer
  - encrypt output buffer
  - XOR in the input
Faster than encrypting a block at a time.
This commit is contained in:
Sean Parkinson
2022-07-08 09:56:20 +10:00
parent 4e1e1e922a
commit 2bfac42d65

View File

@ -4470,30 +4470,54 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
#ifdef WOLFSSL_CHECK_MEM_ZERO #ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch, AES_BLOCK_SIZE); wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch, AES_BLOCK_SIZE);
#endif #endif
/* do as many block size ops as possible */ #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
while (sz >= AES_BLOCK_SIZE) { !defined(XTRANSFORM_AESCTRBLOCK)
#ifdef XTRANSFORM_AESCTRBLOCK if (in != out && sz >= AES_BLOCK_SIZE) {
XTRANSFORM_AESCTRBLOCK(aes, out, in); int blocks = sz / AES_BLOCK_SIZE;
#else byte* counter = (byte*)aes->reg;
ret = wc_AesEncrypt(aes, (byte*)aes->reg, scratch); byte* c = out;
if (ret != 0) { while (blocks--) {
ForceZero(scratch, AES_BLOCK_SIZE); XMEMCPY(c, counter, AES_BLOCK_SIZE);
#ifdef WOLFSSL_CHECK_MEM_ZERO c += AES_BLOCK_SIZE;
wc_MemZero_Check(scratch, AES_BLOCK_SIZE); IncrementAesCounter(counter);
#endif
return ret;
} }
xorbuf(scratch, in, AES_BLOCK_SIZE);
XMEMCPY(out, scratch, AES_BLOCK_SIZE);
#endif
IncrementAesCounter((byte*)aes->reg);
out += AES_BLOCK_SIZE; /* reset number of blocks and then do encryption */
in += AES_BLOCK_SIZE; blocks = sz / AES_BLOCK_SIZE;
sz -= AES_BLOCK_SIZE; wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
aes->left = 0; xorbuf(out, in, AES_BLOCK_SIZE * blocks);
in += AES_BLOCK_SIZE * blocks;
out += AES_BLOCK_SIZE * blocks;
sz -= blocks * AES_BLOCK_SIZE;
}
else
#endif
{
/* do as many block size ops as possible */
while (sz >= AES_BLOCK_SIZE) {
#ifdef XTRANSFORM_AESCTRBLOCK
XTRANSFORM_AESCTRBLOCK(aes, out, in);
#else
ret = wc_AesEncrypt(aes, (byte*)aes->reg, scratch);
if (ret != 0) {
ForceZero(scratch, AES_BLOCK_SIZE);
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(scratch, AES_BLOCK_SIZE);
#endif
return ret;
}
xorbuf(scratch, in, AES_BLOCK_SIZE);
XMEMCPY(out, scratch, AES_BLOCK_SIZE);
#endif
IncrementAesCounter((byte*)aes->reg);
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
sz -= AES_BLOCK_SIZE;
aes->left = 0;
}
ForceZero(scratch, AES_BLOCK_SIZE);
} }
ForceZero(scratch, AES_BLOCK_SIZE);
/* handle non block size remaining and store unused byte count in left */ /* handle non block size remaining and store unused byte count in left */
if (sz) { if (sz) {