Add EVP_CIPHER_CTX_max_next_update and EVP_CIPHER_CTX_max_final

This is intended to replace Conscrypt's current reaching into
EVP_CIPHER_CTX internals to do the calculation itself.

I've bumped BORINGSSL_API_VERSION to help coordinate, but I suspect this
one will be easiest handled by waiting for all the copies of BoringSSL
to update, since it changes the C++ <-> JNI boundary.

Change-Id: Ic28c9463bc66ddd0e25945a3293803191c9e628a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/96327
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Rudolf Polzer <rpolzer@google.com>
diff --git a/crypto/cipher/cipher_test.cc b/crypto/cipher/cipher_test.cc
index 665f344..57aee67 100644
--- a/crypto/cipher/cipher_test.cc
+++ b/crypto/cipher/cipher_test.cc
@@ -262,6 +262,7 @@
     size_t todo = chunk_size == 0 ? in.size() : std::min(in.size(), chunk_size);
     EXPECT_LE(todo, static_cast<size_t>(INT_MAX));
     ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
+    size_t max = EVP_CIPHER_CTX_max_next_update(ctx.get(), todo);
     switch (api) {
       case API::kCipher:
         // `EVP_Cipher` sometimes returns the number of bytes written, or -1 on
@@ -288,6 +289,9 @@
       }
     }
     ASSERT_GE(len, 0);
+    // `EVP_CIPHER_CTX_max_next_update` is, for all currently-implemented
+    // ciphers, exact.
+    EXPECT_EQ(static_cast<size_t>(len), max);
     total += static_cast<size_t>(len);
     in = in.subspan(todo);
   }
@@ -314,6 +318,8 @@
       }
     }
   } else {
+    ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx));
+    size_t max = EVP_CIPHER_CTX_max_final(ctx.get());
     switch (api) {
       case API::kCipher:
         if (is_custom_cipher) {
@@ -336,6 +342,13 @@
       }
     }
     ASSERT_GE(len, 0);
+    // `EVP_CIPHER_CTX_max_final` is, for currently-implemented ciphers, exact
+    // for all but padded decrypt.
+    if (op == Operation::kDecrypt && padding) {
+      EXPECT_LE(static_cast<size_t>(len), max);
+    } else {
+      EXPECT_EQ(static_cast<size_t>(len), max);
+    }
     total += static_cast<size_t>(len);
     result.resize(total);
     EXPECT_EQ(Bytes(expected), Bytes(result));
diff --git a/crypto/fipsmodule/cipher/cipher.cc.inc b/crypto/fipsmodule/cipher/cipher.cc.inc
index d293f60..49fb979 100644
--- a/crypto/fipsmodule/cipher/cipher.cc.inc
+++ b/crypto/fipsmodule/cipher/cipher.cc.inc
@@ -680,6 +680,49 @@
   }
 }
 
+size_t EVP_CIPHER_CTX_max_next_update(const EVP_CIPHER_CTX *ctx,
+                                      size_t in_len) {
+  if (in_len == 0) {
+    return 0;
+  }
+
+  size_t block_size = ctx->cipher->block_size;
+  // |block_size| must be a power of 2.
+  assert(block_size != 0 && (block_size & (block_size - 1)) == 0);
+  size_t buf_len = ctx->buf_len;
+
+  // Any buffered input is combined with |in_len|, then we round down to a
+  // multiple of the block size.
+  size_t ret = (in_len + buf_len) & ~(block_size - 1);
+  if (!ctx->encrypt && block_size > 1 && !(ctx->flags & EVP_CIPH_NO_PADDING)) {
+    if (ctx->final_used) {
+      // There was a buffered decrypted block. Now that it is known to not have
+      // padding, DecryptUpdate will output it.
+      ret += block_size;
+    }
+    if (block_remainder(ctx, in_len + buf_len) == 0) {
+      // This call ends on a block boundary. The last block will be buffered in
+      // |ctx->final| until it is known to have padding.
+      assert(ret >= block_size);
+      ret -= block_size;
+    }
+  }
+  return ret;
+}
+
+size_t EVP_CIPHER_CTX_max_final(const EVP_CIPHER_CTX *ctx) {
+  size_t block_size = ctx->cipher->block_size;
+  if (block_size == 1 || (ctx->flags & EVP_CIPH_NO_PADDING)) {
+    return 0;
+  }
+  if (ctx->encrypt) {
+    return block_size;
+  } else {
+    // At least one byte will be removed when processing padding.
+    return block_size - 1;
+  }
+}
+
 const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) {
   return ctx->cipher;
 }
diff --git a/include/openssl/base.h b/include/openssl/base.h
index 8ded377..82d5a84 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -73,7 +73,7 @@
 // A consumer may use this symbol in the preprocessor to temporarily build
 // against multiple revisions of BoringSSL at the same time. It is not
 // recommended to do so for longer than is necessary.
-#define BORINGSSL_API_VERSION 41
+#define BORINGSSL_API_VERSION 42
 
 #if defined(BORINGSSL_SHARED_LIBRARY)
 
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
index 285e2e5..0b27aa8 100644
--- a/include/openssl/cipher.h
+++ b/include/openssl/cipher.h
@@ -170,12 +170,13 @@
 // Cipher operations.
 
 // EVP_EncryptUpdate_ex encrypts `in_len` bytes from `in` and writes up to
-// `max_out` bytes of ciphertext to `out`. On success, it sets `*out_len` to
+// `max_out_len` bytes of ciphertext to `out`. On success, it sets `*out_len` to
 // the number of output bytes and returns one. Otherwise, it returns zero.
 //
-// If `max_out` is not large enough for the output, the function will return
+// If `max_out_len` is not large enough for the output, the function will return
 // zero. The size of output buffer needed depends on the cipher and the number
-// of bytes encrypted by `ctx` thus far.
+// of bytes encrypted by `ctx` thus far. `EVP_CIPHER_CTX_max_next_update` will
+// return the maximum output for this call.
 //
 // In ciphers whose block size is not 1, such as CBC, individual calls to
 // `EVP_EncryptUpdate_ex` may output more or less than `in_len` bytes: a single
@@ -188,12 +189,13 @@
                                         const uint8_t *in, size_t in_len);
 
 // EVP_EncryptFinal_ex2 finishes an encryption operation and writes up to
-// `max_out` bytes of output to out. On success, it sets `*out_len` to the
+// `max_out_len` bytes of output to out. On success, it sets `*out_len` to the
 // number of bytes written and returns one. Otherwise, it returns zero.
 //
-// If `max_out` is not large enough for the output, the function will return
+// If `max_out_len` is not large enough for the output, the function will return
 // zero. The size of output buffer needed depends on the cipher and the number
-// of bytes encrypted.
+// of bytes encrypted. `EVP_CIPHER_CTX_max_final` will return the maximum output
+// for this call.
 //
 // If the block size is 1, there will be no final output at all; otherwise, at
 // most one block of ciphertext will be written to the output.
@@ -207,12 +209,13 @@
                                         size_t *out_len, size_t max_out_len);
 
 // EVP_DecryptUpdate_ex decrypts `in_len` bytes from `in` and writes up to
-// `max_out` bytes of plaintext to `out`. On success, it sets `*out_len` to
+// `max_out_len` bytes of plaintext to `out`. On success, it sets `*out_len` to
 // the number of output bytes and returns one. Otherwise, it returns zero.
 //
-// If `max_out` is not large enough for the output, the function will return
+// If `max_out_len` is not large enough for the output, the function will return
 // zero. The size of output buffer needed depends on the cipher and the number
-// of bytes decrypted by `ctx` thus far.
+// of bytes decrypted by `ctx` thus far. `EVP_CIPHER_CTX_max_next_update` will
+// return the maximum output for this call.
 //
 // In ciphers whose block size is not 1, such as CBC, individual calls to
 // `EVP_DecryptUpdate_ex` may output more or less than `in_len` bytes: a single
@@ -228,12 +231,13 @@
                                         const uint8_t *in, size_t in_len);
 
 // EVP_DecryptFinal_ex2 finishes a decryption operation and writes up to
-// `max_out` bytes of output to out. On success, it sets `*out_len` to the
+// `max_out_len` bytes of output to out. On success, it sets `*out_len` to the
 // number of bytes written and returns one. Otherwise, it returns zero.
 //
-// If `max_out` is not large enough for the output, the function will return
+// If `max_out_len` is not large enough for the output, the function will return
 // zero. The size of output buffer needed depends on the cipher and the number
-// of bytes decrypted.
+// of bytes decrypted. `EVP_CIPHER_CTX_max_final` will return the maximum output
+// for this call.
 //
 // If the block size is 1, there will be no final output at all; otherwise, at
 // most one block of ciphertext will be written to the output.
@@ -265,6 +269,19 @@
 OPENSSL_EXPORT int EVP_CipherFinal_ex2(EVP_CIPHER_CTX *ctx, uint8_t *out,
                                        size_t *out_len, size_t max_out_len);
 
+// EVP_CIPHER_CTX_max_next_update returns the maximum number of bytes that may
+// be output from `ctx` by a call to `EVP_CipherUpdate_ex` with `in_len` bytes
+// of input. This takes the current state of `ctx` into account, so the output
+// will change as bytes are passed in and out.
+OPENSSL_EXPORT size_t EVP_CIPHER_CTX_max_next_update(const EVP_CIPHER_CTX *ctx,
+                                                     size_t in_len);
+
+// EVP_CIPHER_CTX_max_final returns the maximum number of bytes that may
+// be output from `ctx` by a call to `EVP_CipherFinal_ex2`. This takes the
+// current state of `ctx` into account, so the output will change as bytes are
+// passed in and out.
+OPENSSL_EXPORT size_t EVP_CIPHER_CTX_max_final(const EVP_CIPHER_CTX *ctx);
+
 
 // Cipher context accessors.
 
diff --git a/include/openssl/prefix_symbols.h b/include/openssl/prefix_symbols.h
index 5adae37..5dd00f9 100644
--- a/include/openssl/prefix_symbols.h
+++ b/include/openssl/prefix_symbols.h
@@ -965,6 +965,8 @@
 #pragma redefine_extname EVP_CIPHER_CTX_init BORINGSSL_ADD_USER_LABEL_AND_PREFIX(EVP_CIPHER_CTX_init)
 #pragma redefine_extname EVP_CIPHER_CTX_iv_length BORINGSSL_ADD_USER_LABEL_AND_PREFIX(EVP_CIPHER_CTX_iv_length)
 #pragma redefine_extname EVP_CIPHER_CTX_key_length BORINGSSL_ADD_USER_LABEL_AND_PREFIX(EVP_CIPHER_CTX_key_length)
+#pragma redefine_extname EVP_CIPHER_CTX_max_final BORINGSSL_ADD_USER_LABEL_AND_PREFIX(EVP_CIPHER_CTX_max_final)
+#pragma redefine_extname EVP_CIPHER_CTX_max_next_update BORINGSSL_ADD_USER_LABEL_AND_PREFIX(EVP_CIPHER_CTX_max_next_update)
 #pragma redefine_extname EVP_CIPHER_CTX_mode BORINGSSL_ADD_USER_LABEL_AND_PREFIX(EVP_CIPHER_CTX_mode)
 #pragma redefine_extname EVP_CIPHER_CTX_new BORINGSSL_ADD_USER_LABEL_AND_PREFIX(EVP_CIPHER_CTX_new)
 #pragma redefine_extname EVP_CIPHER_CTX_nid BORINGSSL_ADD_USER_LABEL_AND_PREFIX(EVP_CIPHER_CTX_nid)
@@ -4081,6 +4083,8 @@
 #define EVP_CIPHER_CTX_init BORINGSSL_ADD_PREFIX(EVP_CIPHER_CTX_init)
 #define EVP_CIPHER_CTX_iv_length BORINGSSL_ADD_PREFIX(EVP_CIPHER_CTX_iv_length)
 #define EVP_CIPHER_CTX_key_length BORINGSSL_ADD_PREFIX(EVP_CIPHER_CTX_key_length)
+#define EVP_CIPHER_CTX_max_final BORINGSSL_ADD_PREFIX(EVP_CIPHER_CTX_max_final)
+#define EVP_CIPHER_CTX_max_next_update BORINGSSL_ADD_PREFIX(EVP_CIPHER_CTX_max_next_update)
 #define EVP_CIPHER_CTX_mode BORINGSSL_ADD_PREFIX(EVP_CIPHER_CTX_mode)
 #define EVP_CIPHER_CTX_new BORINGSSL_ADD_PREFIX(EVP_CIPHER_CTX_new)
 #define EVP_CIPHER_CTX_nid BORINGSSL_ADD_PREFIX(EVP_CIPHER_CTX_nid)