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
|
#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) {
|
||||||
|
Reference in New Issue
Block a user