Return the correct value in EVP_CIPHER_CTX_iv_length after EVP_CTRL_AEAD_SET_IVLEN
Previously, EVP_CIPHER_CTX_iv_length always returned the cipher's fixed IV length. Now, after modification with EVP_CTRL_AEAD_SET_IVLEN, it returns the correct value.
Fixed: 626
Change-Id: Id98c929439850b3e83a80111f35aabebc6e5d47a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/62907
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
diff --git a/crypto/cipher_extra/cipher_test.cc b/crypto/cipher_extra/cipher_test.cc
index 6101ef9..9375bc1 100644
--- a/crypto/cipher_extra/cipher_test.cc
+++ b/crypto/cipher_extra/cipher_test.cc
@@ -211,6 +211,7 @@
ASSERT_LE(iv.size(), size_t{INT_MAX});
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN,
static_cast<int>(iv.size()), 0));
+ ASSERT_EQ(EVP_CIPHER_CTX_iv_length(ctx.get()), iv.size());
} else {
ASSERT_EQ(iv.size(), EVP_CIPHER_CTX_iv_length(ctx.get()));
}
diff --git a/crypto/fipsmodule/cipher/cipher.c b/crypto/fipsmodule/cipher/cipher.c
index 18b5e0a..bff7996 100644
--- a/crypto/fipsmodule/cipher/cipher.c
+++ b/crypto/fipsmodule/cipher/cipher.c
@@ -586,6 +586,16 @@
}
unsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) {
+ if (EVP_CIPHER_mode(ctx->cipher) == EVP_CIPH_GCM_MODE) {
+ int length;
+ int res = EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)ctx, EVP_CTRL_GET_IVLEN, 0,
+ &length);
+ // EVP_CIPHER_CTX_ctrl returning an error should be impossible under this
+ // circumstance. If it somehow did, fallback to the static cipher iv_len.
+ if (res == 1) {
+ return length;
+ }
+ }
return ctx->cipher->iv_len;
}
diff --git a/crypto/fipsmodule/cipher/e_aes.c b/crypto/fipsmodule/cipher/e_aes.c
index 0db77b8..6d91cc4 100644
--- a/crypto/fipsmodule/cipher/e_aes.c
+++ b/crypto/fipsmodule/cipher/e_aes.c
@@ -454,6 +454,10 @@
gctx->ivlen = arg;
return 1;
+ case EVP_CTRL_GET_IVLEN:
+ *(int *)ptr = gctx->ivlen;
+ return 1;
+
case EVP_CTRL_AEAD_SET_TAG:
if (arg <= 0 || arg > 16 || c->encrypt) {
return 0;
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
index 310d7c2..18c1e70 100644
--- a/include/openssl/cipher.h
+++ b/include/openssl/cipher.h
@@ -542,6 +542,7 @@
#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
// EVP_CTRL_GCM_SET_IV_INV sets the GCM invocation field, decrypt only
#define EVP_CTRL_GCM_SET_IV_INV 0x18
+#define EVP_CTRL_GET_IVLEN 0x19
// The following constants are unused.
#define EVP_GCM_TLS_FIXED_IV_LEN 4