Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/Crypto/Util/Padding.py: 24%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

37 statements  

1# 

2# Util/Padding.py : Functions to manage padding 

3# 

4# SPDX-FileCopyrightText: 2014 Legrandin <helderijs@gmail.com> 

5# SPDX-License-Identifier: BSD-2-Clause 

6 

7from __future__ import annotations 

8 

9from typing import Optional 

10 

11__all__ = ["pad", "unpad"] 

12 

13 

14def pad(data_to_pad: bytes, block_size: int, style: Optional[str] = "pkcs7") -> bytes: 

15 """Apply standard padding. 

16 

17 Args: 

18 data_to_pad (byte string): 

19 The data that needs to be padded. 

20 block_size (integer): 

21 The block boundary to use for padding. The output length is guaranteed 

22 to be a multiple of :data:`block_size`. 

23 style (string): 

24 Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*. 

25 

26 Return: 

27 byte string : the original data with the appropriate padding added at the end. 

28 """ 

29 

30 padding_len = block_size - len(data_to_pad) % block_size 

31 

32 if style == "pkcs7": 

33 padding = bytes([padding_len]) * padding_len 

34 elif style == "x923": 

35 padding = bytes([0]) * (padding_len - 1) + bytes([padding_len]) 

36 elif style == "iso7816": 

37 padding = bytes([128]) + bytes([0]) * (padding_len - 1) 

38 else: 

39 raise ValueError("Unknown padding style") 

40 

41 return data_to_pad + padding 

42 

43 

44def unpad(padded_data: bytes, block_size: int, style: Optional[str] = "pkcs7") -> bytes: 

45 """Remove standard padding. 

46 

47 Args: 

48 padded_data (byte string): 

49 A piece of data with padding that needs to be stripped. 

50 block_size (integer): 

51 The block boundary to use for padding. The input length 

52 must be a multiple of :data:`block_size`. 

53 style (string): 

54 Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*. 

55 Return: 

56 byte string : data without padding. 

57 Raises: 

58 ValueError: if the padding is incorrect. 

59 """ 

60 

61 pdata_len = len(padded_data) 

62 

63 if pdata_len == 0: 

64 raise ValueError("Zero-length input cannot be unpadded") 

65 

66 if pdata_len % block_size: 

67 raise ValueError("Input data is not padded") 

68 

69 if style in ("pkcs7", "x923"): 

70 padding_len = padded_data[-1] 

71 

72 if padding_len < 1 or padding_len > min(block_size, pdata_len): 

73 raise ValueError("Padding is incorrect.") 

74 

75 if style == "pkcs7": 

76 if padded_data[-padding_len:] != bytes([padding_len]) * padding_len: 

77 raise ValueError("PKCS#7 padding is incorrect.") 

78 else: 

79 if padded_data[-padding_len:-1] != bytes([0]) * (padding_len - 1): 

80 raise ValueError("ANSI X.923 padding is incorrect.") 

81 

82 elif style == "iso7816": 

83 padding_len = pdata_len - padded_data.rfind(bytes([128])) 

84 

85 if padding_len < 1 or padding_len > min(block_size, pdata_len): 

86 raise ValueError("Padding is incorrect.") 

87 

88 if padding_len > 1 and padded_data[1 - padding_len :] != bytes([0]) * (padding_len - 1): 

89 raise ValueError("ISO 7816-4 padding is incorrect.") 

90 else: 

91 raise ValueError("Unknown padding style") 

92 

93 return padded_data[:-padding_len]