Test both streaming and single-shot EVP_CIPHER operations.

Run a variant of every test which feeds the input in one byte at a time.

Change-Id: I2a05372ea0fbb20484493fd14e9f3c23fbb8d875
Reviewed-on: https://boringssl-review.googlesource.com/5301
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/cipher/cipher_test.cc b/crypto/cipher/cipher_test.cc
index 97a84e0..18f75b1 100644
--- a/crypto/cipher/cipher_test.cc
+++ b/crypto/cipher/cipher_test.cc
@@ -104,6 +104,7 @@
 static bool TestOperation(FileTest *t,
                           const EVP_CIPHER *cipher,
                           bool encrypt,
+                          bool streaming,
                           const std::vector<uint8_t> &key,
                           const std::vector<uint8_t> &iv,
                           const std::vector<uint8_t> &plaintext,
@@ -160,11 +161,29 @@
       (!aad.empty() &&
        !EVP_CipherUpdate(ctx.get(), nullptr, &unused, bssl::vector_data(&aad),
                          aad.size())) ||
-      !EVP_CIPHER_CTX_set_padding(ctx.get(), 0) ||
-      (!in->empty() &&
-       !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result), &result_len1,
-                         bssl::vector_data(in), in->size())) ||
-      !EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1,
+      !EVP_CIPHER_CTX_set_padding(ctx.get(), 0)) {
+    t->PrintLine("Operation failed.");
+    return false;
+  }
+  if (streaming) {
+    for (size_t i = 0; i < in->size(); i++) {
+      uint8_t c = (*in)[i];
+      int len;
+      if (!EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result) + result_len1,
+                            &len, &c, 1)) {
+        t->PrintLine("Operation failed.");
+        return false;
+      }
+      result_len1 += len;
+    }
+  } else if (!in->empty() &&
+             !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result),
+                               &result_len1, bssl::vector_data(in),
+                               in->size())) {
+    t->PrintLine("Operation failed.");
+    return false;
+  }
+  if (!EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1,
                           &result_len2)) {
     t->PrintLine("Operation failed.");
     return false;
@@ -236,15 +255,21 @@
   }
 
   // By default, both directions are run, unless overridden by the operation.
-  if (operation != kDecrypt &&
-      !TestOperation(t, cipher, true /* encrypt */, key, iv, plaintext,
-                     ciphertext, aad, tag)) {
-    return false;
+  if (operation != kDecrypt) {
+    if (!TestOperation(t, cipher, true /* encrypt */, false /* single-shot */,
+                       key, iv, plaintext, ciphertext, aad, tag) ||
+        !TestOperation(t, cipher, true /* encrypt */, true /* streaming */, key,
+                       iv, plaintext, ciphertext, aad, tag)) {
+      return false;
+    }
   }
-  if (operation != kEncrypt &&
-      !TestOperation(t, cipher, false /* decrypt */, key, iv, plaintext,
-                     ciphertext, aad, tag)) {
-    return false;
+  if (operation != kEncrypt) {
+    if (!TestOperation(t, cipher, false /* decrypt */, false /* single-shot */,
+                       key, iv, plaintext, ciphertext, aad, tag) ||
+        !TestOperation(t, cipher, false /* decrypt */, true /* streaming */,
+                       key, iv, plaintext, ciphertext, aad, tag)) {
+      return false;
+    }
   }
 
   return true;