Merge pull request #418 from reaperhulk/move-contexts

Move ciphercontext/aeadciphercontext to bottom of symmetric encryption
diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst
index c1f7bb6..2233d52 100644
--- a/docs/hazmat/primitives/symmetric-encryption.rst
+++ b/docs/hazmat/primitives/symmetric-encryption.rst
@@ -291,8 +291,6 @@
             Cipher, algorithms, modes
         )
 
-        from cryptography.hazmat.primitives.padding import PKCS7
-
         def encrypt(key, plaintext, associated_data):
             # Generate a random 96-bit IV.
             iv = os.urandom(12)
@@ -305,17 +303,13 @@
                 backend=default_backend()
             ).encryptor()
 
-            # We have to pad our plaintext because it may not be a
-            # multiple of the block size.
-            padder = PKCS7(algorithms.AES.block_size).padder()
-            padded_plaintext = padder.update(plaintext) + padder.finalize()
-
             # associated_data will be authenticated but not encrypted,
             # it must also be passed in on decryption.
             encryptor.authenticate_additional_data(associated_data)
 
             # Encrypt the plaintext and get the associated ciphertext.
-            ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize()
+            # GCM does not require padding.
+            ciphertext = encryptor.update(plaintext) + encryptor.finalize()
 
             return (iv, ciphertext, encryptor.tag)
 
@@ -328,17 +322,13 @@
                 backend=default_backend()
             ).decryptor()
 
-            # We will need to unpad the plaintext.
-            unpadder = PKCS7(algorithms.AES.block_size).unpadder()
-
             # We put associated_data back in or the tag will fail to verify
             # when we finalize the decryptor.
             decryptor.authenticate_additional_data(associated_data)
 
-            # Decryption gets us the authenticated padded plaintext.
-            padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize()
-
-            return unpadder.update(padded_plaintext) + unpadder.finalize()
+            # Decryption gets us the authenticated plaintext.
+            # If the tag does not match an InvalidTag exception will be raised.
+            return decryptor.update(ciphertext) + decryptor.finalize()
 
         iv, ciphertext, tag = encrypt(
             key,