Added support for padding ANSI X.923
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index a203a16..60d46d5 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -6,6 +6,8 @@
 
 .. note:: This version is not yet released and is under active development.
 
+* Added support for padding ANSI X.923 with
+  :class:`~cryptography.hazmat.primitives.padding.ANSIX923`.
 * Deprecated support for OpenSSL 0.9.8. Support will be removed in
   ``cryptography`` 1.4.
 
diff --git a/docs/hazmat/primitives/padding.rst b/docs/hazmat/primitives/padding.rst
index a60f5ac..37e4252 100644
--- a/docs/hazmat/primitives/padding.rst
+++ b/docs/hazmat/primitives/padding.rst
@@ -54,6 +54,47 @@
             provider.
 
 
+.. class:: ANSIX923(block_size)
+
+    ANSI X.923 padding works by appending ``N-1`` bytes with the value of ``0``
+    and a last byte with the value of ``chr(N)``, where ``N`` is the number of
+    bytes required to make the final block of data the same size as the block
+    size. A simple example of padding is:
+
+    .. doctest::
+
+        >>> padder = padding.ANSIX923(128).padder()
+        >>> padded_data = padder.update(b"11111111111111112222222222")
+        >>> padded_data
+        '1111111111111111'
+        >>> padded_data += padder.finalize()
+        >>> padded_data
+        '11111111111111112222222222\x00\x00\x00\x00\x00\x06'
+        >>> unpadder = padding.ANSIX923(128).unpadder()
+        >>> data = unpadder.update(padded_data)
+        >>> data
+        '1111111111111111'
+        >>> data + unpadder.finalize()
+        '11111111111111112222222222'
+
+    :param block_size: The size of the block in bits that the data is being
+        padded to.
+    :raises ValueError: Raised if block size is not a multiple of 8 or is not
+        between 0 and 256.
+
+    .. method:: padder()
+
+        :returns: A padding
+            :class:`~cryptography.hazmat.primitives.padding.PaddingContext`
+            provider
+
+    .. method:: unpadder()
+
+        :returns: An unpadding
+            :class:`~cryptography.hazmat.primitives.padding.PaddingContext`
+            provider.
+
+
 .. class:: PaddingContext
 
     When calling ``padder()`` or ``unpadder()`` the result will conform to the
diff --git a/src/cryptography/hazmat/primitives/padding.py b/src/cryptography/hazmat/primitives/padding.py
index f6491eb..72ebff2 100644
--- a/src/cryptography/hazmat/primitives/padding.py
+++ b/src/cryptography/hazmat/primitives/padding.py
@@ -68,12 +68,15 @@
 
         return result
 
+    def _padding(self, size):
+        return six.int2byte(size) * size
+
     def finalize(self):
         if self._buffer is None:
             raise AlreadyFinalized("Context was already finalized.")
 
         pad_size = self.block_size // 8 - len(self._buffer)
-        result = self._buffer + six.int2byte(pad_size) * pad_size
+        result = self._buffer + self._padding(pad_size)
         self._buffer = None
         return result
 
@@ -104,6 +107,11 @@
 
         return result
 
+    def _check_padding(self):
+        return lib.Cryptography_check_pkcs7_padding(
+            self._buffer, self.block_size // 8
+        )
+
     def finalize(self):
         if self._buffer is None:
             raise AlreadyFinalized("Context was already finalized.")
@@ -111,9 +119,7 @@
         if len(self._buffer) != self.block_size // 8:
             raise ValueError("Invalid padding bytes.")
 
-        valid = lib.Cryptography_check_pkcs7_padding(
-            self._buffer, self.block_size // 8
-        )
+        valid = self._check_padding()
 
         if not valid:
             raise ValueError("Invalid padding bytes.")
@@ -122,3 +128,26 @@
         res = self._buffer[:-pad_size]
         self._buffer = None
         return res
+
+
+class ANSIX923(PKCS7):
+
+    def padder(self):
+        return _ANSIX923PaddingContext(self.block_size)
+
+    def unpadder(self):
+        return _ANSIX923UnpaddingContext(self.block_size)
+
+
+@utils.register_interface(PaddingContext)
+class _ANSIX923PaddingContext(_PKCS7PaddingContext):
+
+    def _padding(self, size):
+        return six.int2byte(0) * (size - 1) + six.int2byte(size)
+
+
+@utils.register_interface(PaddingContext)
+class _ANSIX923UnpaddingContext(_PKCS7UnpaddingContext):
+
+    def _check_padding(self):
+        return True
diff --git a/tests/hazmat/primitives/test_padding.py b/tests/hazmat/primitives/test_padding.py
index 392ea73..9da8ea7 100644
--- a/tests/hazmat/primitives/test_padding.py
+++ b/tests/hazmat/primitives/test_padding.py
@@ -99,3 +99,51 @@
             unpadder.update(b"")
         with pytest.raises(AlreadyFinalized):
             unpadder.finalize()
+
+
+class TestANSIX923(object):
+    @pytest.mark.parametrize(("size", "unpadded", "padded"), [
+        (
+            128,
+            b"1111111111",
+            b"1111111111\x00\x00\x00\x00\x00\x06",
+        ),
+        (
+            128,
+            b"111111111111111122222222222222",
+            b"111111111111111122222222222222\x00\x02",
+        ),
+        (
+            128,
+            b"1" * 16,
+            b"1" * 16 + b"\x00" * 15 + b"\x10",
+        ),
+        (
+            128,
+            b"1" * 17,
+            b"1" * 17 + b"\x00" * 14 + b"\x0F",
+        )
+    ])
+    def test_pad(self, size, unpadded, padded):
+        padder = padding.ANSIX923(size).padder()
+        result = padder.update(unpadded)
+        result += padder.finalize()
+        assert result == padded
+
+    @pytest.mark.parametrize(("size", "unpadded", "padded"), [
+        (
+            128,
+            b"1111111111",
+            b"1111111111\x00\x00\x00\x00\x00\x06",
+        ),
+        (
+            128,
+            b"111111111111111122222222222222",
+            b"111111111111111122222222222222\x00\x02",
+        ),
+    ])
+    def test_unpad(self, size, unpadded, padded):
+        unpadder = padding.ANSIX923(size).unpadder()
+        result = unpadder.update(padded)
+        result += unpadder.finalize()
+        assert result == unpadded
diff --git a/tests/hypothesis/test_padding.py b/tests/hypothesis/test_padding.py
index 21c9a23..29d726f 100644
--- a/tests/hypothesis/test_padding.py
+++ b/tests/hypothesis/test_padding.py
@@ -5,7 +5,7 @@
 from hypothesis import given
 from hypothesis.strategies import binary, integers
 
-from cryptography.hazmat.primitives.padding import PKCS7
+from cryptography.hazmat.primitives.padding import ANSIX923, PKCS7
 
 
 @given(integers(min_value=1, max_value=31), binary())
@@ -19,3 +19,14 @@
     padded = padder.update(data) + padder.finalize()
 
     assert unpadder.update(padded) + unpadder.finalize() == data
+
+
+@given(integers(min_value=1, max_value=31), binary())
+def test_ansix923(block_size, data):
+    a = ANSIX923(block_size=block_size * 8)
+    padder = a.padder()
+    unpadder = a.unpadder()
+
+    padded = padder.update(data) + padder.finalize()
+
+    assert unpadder.update(padded) + unpadder.finalize() == data