Spaces:
Runtime error
Runtime error
| # | |
| # Util/Padding.py : Functions to manage padding | |
| # | |
| # =================================================================== | |
| # | |
| # Copyright (c) 2014, Legrandin <helderijs@gmail.com> | |
| # All rights reserved. | |
| # | |
| # Redistribution and use in source and binary forms, with or without | |
| # modification, are permitted provided that the following conditions | |
| # are met: | |
| # | |
| # 1. Redistributions of source code must retain the above copyright | |
| # notice, this list of conditions and the following disclaimer. | |
| # 2. Redistributions in binary form must reproduce the above copyright | |
| # notice, this list of conditions and the following disclaimer in | |
| # the documentation and/or other materials provided with the | |
| # distribution. | |
| # | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
| # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
| # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
| # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |
| # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| # POSSIBILITY OF SUCH DAMAGE. | |
| # =================================================================== | |
| __all__ = [ 'pad', 'unpad' ] | |
| from Crypto.Util.py3compat import * | |
| def pad(data_to_pad, block_size, style='pkcs7'): | |
| """Apply standard padding. | |
| Args: | |
| data_to_pad (byte string): | |
| The data that needs to be padded. | |
| block_size (integer): | |
| The block boundary to use for padding. The output length is guaranteed | |
| to be a multiple of :data:`block_size`. | |
| style (string): | |
| Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*. | |
| Return: | |
| byte string : the original data with the appropriate padding added at the end. | |
| """ | |
| padding_len = block_size-len(data_to_pad)%block_size | |
| if style == 'pkcs7': | |
| padding = bchr(padding_len)*padding_len | |
| elif style == 'x923': | |
| padding = bchr(0)*(padding_len-1) + bchr(padding_len) | |
| elif style == 'iso7816': | |
| padding = bchr(128) + bchr(0)*(padding_len-1) | |
| else: | |
| raise ValueError("Unknown padding style") | |
| return data_to_pad + padding | |
| def unpad(padded_data, block_size, style='pkcs7'): | |
| """Remove standard padding. | |
| Args: | |
| padded_data (byte string): | |
| A piece of data with padding that needs to be stripped. | |
| block_size (integer): | |
| The block boundary to use for padding. The input length | |
| must be a multiple of :data:`block_size`. | |
| style (string): | |
| Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*. | |
| Return: | |
| byte string : data without padding. | |
| Raises: | |
| ValueError: if the padding is incorrect. | |
| """ | |
| pdata_len = len(padded_data) | |
| if pdata_len == 0: | |
| raise ValueError("Zero-length input cannot be unpadded") | |
| if pdata_len % block_size: | |
| raise ValueError("Input data is not padded") | |
| if style in ('pkcs7', 'x923'): | |
| padding_len = bord(padded_data[-1]) | |
| if padding_len<1 or padding_len>min(block_size, pdata_len): | |
| raise ValueError("Padding is incorrect.") | |
| if style == 'pkcs7': | |
| if padded_data[-padding_len:]!=bchr(padding_len)*padding_len: | |
| raise ValueError("PKCS#7 padding is incorrect.") | |
| else: | |
| if padded_data[-padding_len:-1]!=bchr(0)*(padding_len-1): | |
| raise ValueError("ANSI X.923 padding is incorrect.") | |
| elif style == 'iso7816': | |
| padding_len = pdata_len - padded_data.rfind(bchr(128)) | |
| if padding_len<1 or padding_len>min(block_size, pdata_len): | |
| raise ValueError("Padding is incorrect.") | |
| if padding_len>1 and padded_data[1-padding_len:]!=bchr(0)*(padding_len-1): | |
| raise ValueError("ISO 7816-4 padding is incorrect.") | |
| else: | |
| raise ValueError("Unknown padding style") | |
| return padded_data[:-padding_len] | |