From c339c702f6043fabd09904044f967e71629bc40f Mon Sep 17 00:00:00 2001 From: Kurt Roeckx Date: Sun, 16 Feb 2020 14:44:06 +0100 Subject: [PATCH] Improve small block cipher performance Avoid function calls we don't need to do. In 1.1.1 we have: aes-128-cbc 572267.80k 681197.08k 715430.74k 720508.59k 722359.64k 723004.07k Current master: aes-128-cbc 460663.70k 631125.66k 701283.58k 719794.52k 724732.59k 726668.63k new: aes-128-cbc 582057.64k 684288.62k 715721.90k 724856.15k 717578.24k 727176.53k Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/11102) --- .../implementations/ciphers/cipher_aes_ocb.c | 9 +++++++-- .../implementations/ciphers/ciphercommon.c | 9 +++++++-- .../ciphers/ciphercommon_block.c | 17 +++++++---------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/providers/implementations/ciphers/cipher_aes_ocb.c b/providers/implementations/ciphers/cipher_aes_ocb.c index 2f85604a87..3d4863ea03 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb.c +++ b/providers/implementations/ciphers/cipher_aes_ocb.c @@ -150,9 +150,14 @@ static int aes_ocb_block_update_internal(PROV_AES_OCB_CTX *ctx, size_t outsize, const unsigned char *in, size_t inl, OSSL_ocb_cipher_fn ciph) { - size_t nextblocks = fillblock(buf, bufsz, AES_BLOCK_SIZE, &in, &inl); + size_t nextblocks; size_t outlint = 0; + if (bufsz != 0) + nextblocks = fillblock(buf, bufsz, AES_BLOCK_SIZE, &in, &inl); + else + nextblocks = inl & ~(AES_BLOCK_SIZE-1); + if (*bufsz == AES_BLOCK_SIZE) { if (outsize < AES_BLOCK_SIZE) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); @@ -179,7 +184,7 @@ static int aes_ocb_block_update_internal(PROV_AES_OCB_CTX *ctx, in += nextblocks; inl -= nextblocks; } - if (!trailingdata(buf, bufsz, AES_BLOCK_SIZE, &in, &inl)) { + if (inl != 0 && !trailingdata(buf, bufsz, AES_BLOCK_SIZE, &in, &inl)) { /* PROVerr already called */ return 0; } diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c index 967622cf64..33afa57585 100644 --- a/providers/implementations/ciphers/ciphercommon.c +++ b/providers/implementations/ciphers/ciphercommon.c @@ -176,7 +176,12 @@ int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl, size_t outlint = 0; PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; size_t blksz = ctx->blocksize; - size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, blksz, &in, &inl); + size_t nextblocks; + + if (ctx->bufsz != 0) + nextblocks = fillblock(ctx->buf, &ctx->bufsz, blksz, &in, &inl); + else + nextblocks = inl & ~(blksz-1); /* * If we're decrypting and we end an update on a block boundary we hold @@ -218,7 +223,7 @@ int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl, in += nextblocks; inl -= nextblocks; } - if (!trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) { + if (inl != 0 && !trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) { /* ERR_raise already called */ return 0; } diff --git a/providers/implementations/ciphers/ciphercommon_block.c b/providers/implementations/ciphers/ciphercommon_block.c index eff94842ed..ee54f481c6 100644 --- a/providers/implementations/ciphers/ciphercommon_block.c +++ b/providers/implementations/ciphers/ciphercommon_block.c @@ -35,20 +35,17 @@ size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize, const unsigned char **in, size_t *inlen) { size_t blockmask = ~(blocksize - 1); + size_t bufremain = blocksize - *buflen; assert(*buflen <= blocksize); assert(blocksize > 0 && (blocksize & (blocksize - 1)) == 0); - if (*buflen != blocksize && (*buflen != 0 || *inlen < blocksize)) { - size_t bufremain = blocksize - *buflen; - - if (*inlen < bufremain) - bufremain = *inlen; - memcpy(buf + *buflen, *in, bufremain); - *in += bufremain; - *inlen -= bufremain; - *buflen += bufremain; - } + if (*inlen < bufremain) + bufremain = *inlen; + memcpy(buf + *buflen, *in, bufremain); + *in += bufremain; + *inlen -= bufremain; + *buflen += bufremain; return *inlen & blockmask; } -- 2.34.1