forked from wolfSSL/wolfssl
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:
@ -4470,30 +4470,54 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||
wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch, AES_BLOCK_SIZE);
|
||||
#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;
|
||||
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
|
||||
!defined(XTRANSFORM_AESCTRBLOCK)
|
||||
if (in != out && sz >= AES_BLOCK_SIZE) {
|
||||
int blocks = sz / AES_BLOCK_SIZE;
|
||||
byte* counter = (byte*)aes->reg;
|
||||
byte* c = out;
|
||||
while (blocks--) {
|
||||
XMEMCPY(c, counter, AES_BLOCK_SIZE);
|
||||
c += AES_BLOCK_SIZE;
|
||||
IncrementAesCounter(counter);
|
||||
}
|
||||
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;
|
||||
/* reset number of blocks and then do encryption */
|
||||
blocks = sz / AES_BLOCK_SIZE;
|
||||
wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
|
||||
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 */
|
||||
if (sz) {
|
||||
|
Reference in New Issue
Block a user