1#
2#  SelfTest/Util/test_Padding.py: Self-test for padding functions
3#
4# ===================================================================
5#
6# Copyright (c) 2014, Legrandin <helderijs@gmail.com>
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12#
13# 1. Redistributions of source code must retain the above copyright
14#    notice, this list of conditions and the following disclaimer.
15# 2. Redistributions in binary form must reproduce the above copyright
16#    notice, this list of conditions and the following disclaimer in
17#    the documentation and/or other materials provided with the
18#    distribution.
19#
20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31# POSSIBILITY OF SUCH DAMAGE.
32# ===================================================================
33
34import unittest
35from binascii import unhexlify as uh
36
37from Crypto.Util.py3compat import *
38from Crypto.SelfTest.st_common import list_test_cases
39from Crypto.Util.Padding import pad, unpad
40
41class PKCS7_Tests(unittest.TestCase):
42
43    def test1(self):
44        padded = pad(b(""), 4)
45        self.failUnless(padded == uh(b("04040404")))
46        padded = pad(b(""), 4, 'pkcs7')
47        self.failUnless(padded == uh(b("04040404")))
48        back = unpad(padded, 4)
49        self.failUnless(back == b(""))
50
51    def test2(self):
52        padded = pad(uh(b("12345678")), 4)
53        self.failUnless(padded == uh(b("1234567804040404")))
54        back = unpad(padded, 4)
55        self.failUnless(back == uh(b("12345678")))
56
57    def test3(self):
58        padded = pad(uh(b("123456")), 4)
59        self.failUnless(padded == uh(b("12345601")))
60        back = unpad(padded, 4)
61        self.failUnless(back == uh(b("123456")))
62
63    def test4(self):
64        padded = pad(uh(b("1234567890")), 4)
65        self.failUnless(padded == uh(b("1234567890030303")))
66        back = unpad(padded, 4)
67        self.failUnless(back == uh(b("1234567890")))
68
69    def testn1(self):
70        self.assertRaises(ValueError, pad, uh(b("12")), 4, 'pkcs8')
71
72    def testn2(self):
73        self.assertRaises(ValueError, unpad, b("\0\0\0"), 4)
74        self.assertRaises(ValueError, unpad, b(""), 4)
75
76    def testn3(self):
77        self.assertRaises(ValueError, unpad, b("123456\x02"), 4)
78        self.assertRaises(ValueError, unpad, b("123456\x00"), 4)
79        self.assertRaises(ValueError, unpad, b("123456\x05\x05\x05\x05\x05"), 4)
80
81class X923_Tests(unittest.TestCase):
82
83    def test1(self):
84        padded = pad(b(""), 4, 'x923')
85        self.failUnless(padded == uh(b("00000004")))
86        back = unpad(padded, 4, 'x923')
87        self.failUnless(back == b(""))
88
89    def test2(self):
90        padded = pad(uh(b("12345678")), 4, 'x923')
91        self.failUnless(padded == uh(b("1234567800000004")))
92        back = unpad(padded, 4, 'x923')
93        self.failUnless(back == uh(b("12345678")))
94
95    def test3(self):
96        padded = pad(uh(b("123456")), 4, 'x923')
97        self.failUnless(padded == uh(b("12345601")))
98        back = unpad(padded, 4, 'x923')
99        self.failUnless(back == uh(b("123456")))
100
101    def test4(self):
102        padded = pad(uh(b("1234567890")), 4, 'x923')
103        self.failUnless(padded == uh(b("1234567890000003")))
104        back = unpad(padded, 4, 'x923')
105        self.failUnless(back == uh(b("1234567890")))
106
107    def testn1(self):
108        self.assertRaises(ValueError, unpad, b("123456\x02"), 4, 'x923')
109        self.assertRaises(ValueError, unpad, b("123456\x00"), 4, 'x923')
110        self.assertRaises(ValueError, unpad, b("123456\x00\x00\x00\x00\x05"), 4, 'x923')
111        self.assertRaises(ValueError, unpad, b(""), 4, 'x923')
112
113class ISO7816_Tests(unittest.TestCase):
114
115    def test1(self):
116        padded = pad(b(""), 4, 'iso7816')
117        self.failUnless(padded == uh(b("80000000")))
118        back = unpad(padded, 4, 'iso7816')
119        self.failUnless(back == b(""))
120
121    def test2(self):
122        padded = pad(uh(b("12345678")), 4, 'iso7816')
123        self.failUnless(padded == uh(b("1234567880000000")))
124        back = unpad(padded, 4, 'iso7816')
125        self.failUnless(back == uh(b("12345678")))
126
127    def test3(self):
128        padded = pad(uh(b("123456")), 4, 'iso7816')
129        self.failUnless(padded == uh(b("12345680")))
130        #import pdb; pdb.set_trace()
131        back = unpad(padded, 4, 'iso7816')
132        self.failUnless(back == uh(b("123456")))
133
134    def test4(self):
135        padded = pad(uh(b("1234567890")), 4, 'iso7816')
136        self.failUnless(padded == uh(b("1234567890800000")))
137        back = unpad(padded, 4, 'iso7816')
138        self.failUnless(back == uh(b("1234567890")))
139
140    def testn1(self):
141        self.assertRaises(ValueError, unpad, b("123456\x81"), 4, 'iso7816')
142        self.assertRaises(ValueError, unpad, b(""), 4, 'iso7816')
143
144def get_tests(config={}):
145    tests = []
146    tests += list_test_cases(PKCS7_Tests)
147    tests += list_test_cases(X923_Tests)
148    tests += list_test_cases(ISO7816_Tests)
149    return tests
150
151if __name__ == '__main__':
152    suite = lambda: unittest.TestSuite(get_tests())
153    unittest.main(defaultTest='suite')
154
155