Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/cryptography/hazmat/primitives/ciphers/modes.py: 59%

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

86 statements  

1# This file is dual licensed under the terms of the Apache License, Version 

2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 

3# for complete details. 

4 

5from __future__ import annotations 

6 

7from cryptography import utils 

8from cryptography.exceptions import UnsupportedAlgorithm, _Reasons 

9from cryptography.hazmat.decrepit.ciphers.modes import CFB as CFB 

10from cryptography.hazmat.decrepit.ciphers.modes import CFB8 as CFB8 

11from cryptography.hazmat.decrepit.ciphers.modes import OFB as OFB 

12from cryptography.hazmat.primitives._cipheralgorithm import ( 

13 BlockCipherAlgorithm, 

14 CipherAlgorithm, 

15) 

16from cryptography.hazmat.primitives._modes import ( 

17 Mode as Mode, 

18) 

19from cryptography.hazmat.primitives._modes import ( 

20 ModeWithAuthenticationTag as ModeWithAuthenticationTag, 

21) 

22from cryptography.hazmat.primitives._modes import ( 

23 ModeWithInitializationVector as ModeWithInitializationVector, 

24) 

25from cryptography.hazmat.primitives._modes import ( 

26 ModeWithNonce as ModeWithNonce, 

27) 

28from cryptography.hazmat.primitives._modes import ( 

29 ModeWithTweak as ModeWithTweak, 

30) 

31from cryptography.hazmat.primitives._modes import ( 

32 _check_aes_key_length, 

33 _check_iv_and_key_length, 

34 _check_nonce_length, 

35) 

36from cryptography.hazmat.primitives.ciphers import algorithms 

37 

38 

39class CBC(ModeWithInitializationVector): 

40 name = "CBC" 

41 

42 def __init__(self, initialization_vector: utils.Buffer): 

43 utils._check_byteslike("initialization_vector", initialization_vector) 

44 self._initialization_vector = initialization_vector 

45 

46 @property 

47 def initialization_vector(self) -> utils.Buffer: 

48 return self._initialization_vector 

49 

50 validate_for_algorithm = _check_iv_and_key_length 

51 

52 

53class XTS(ModeWithTweak): 

54 name = "XTS" 

55 

56 def __init__(self, tweak: utils.Buffer): 

57 utils._check_byteslike("tweak", tweak) 

58 

59 if len(tweak) != 16: 

60 raise ValueError("tweak must be 128-bits (16 bytes)") 

61 

62 self._tweak = tweak 

63 

64 @property 

65 def tweak(self) -> utils.Buffer: 

66 return self._tweak 

67 

68 def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: 

69 if isinstance(algorithm, (algorithms.AES128, algorithms.AES256)): 

70 raise TypeError( 

71 "The AES128 and AES256 classes do not support XTS, please use " 

72 "the standard AES class instead." 

73 ) 

74 

75 if algorithm.key_size not in (256, 512): 

76 raise ValueError( 

77 "The XTS specification requires a 256-bit key for AES-128-XTS" 

78 " and 512-bit key for AES-256-XTS" 

79 ) 

80 

81 

82class ECB(Mode): 

83 name = "ECB" 

84 

85 validate_for_algorithm = _check_aes_key_length 

86 

87 

88class CTR(ModeWithNonce): 

89 name = "CTR" 

90 

91 def __init__(self, nonce: utils.Buffer): 

92 utils._check_byteslike("nonce", nonce) 

93 self._nonce = nonce 

94 

95 @property 

96 def nonce(self) -> utils.Buffer: 

97 return self._nonce 

98 

99 def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: 

100 _check_aes_key_length(self, algorithm) 

101 _check_nonce_length(self.nonce, self.name, algorithm) 

102 

103 

104class GCM(ModeWithInitializationVector, ModeWithAuthenticationTag): 

105 name = "GCM" 

106 _MAX_ENCRYPTED_BYTES = (2**39 - 256) // 8 

107 _MAX_AAD_BYTES = (2**64) // 8 

108 

109 def __init__( 

110 self, 

111 initialization_vector: utils.Buffer, 

112 tag: bytes | None = None, 

113 min_tag_length: int = 16, 

114 ): 

115 # OpenSSL 3.0.0 constrains GCM IVs to [64, 1024] bits inclusive 

116 # This is a sane limit anyway so we'll enforce it here. 

117 utils._check_byteslike("initialization_vector", initialization_vector) 

118 if len(initialization_vector) < 8 or len(initialization_vector) > 128: 

119 raise ValueError( 

120 "initialization_vector must be between 8 and 128 bytes (64 " 

121 "and 1024 bits)." 

122 ) 

123 self._initialization_vector = initialization_vector 

124 if tag is not None: 

125 utils._check_bytes("tag", tag) 

126 if min_tag_length < 4: 

127 raise ValueError("min_tag_length must be >= 4") 

128 if len(tag) < min_tag_length: 

129 raise ValueError( 

130 f"Authentication tag must be {min_tag_length} bytes or " 

131 "longer." 

132 ) 

133 self._tag = tag 

134 self._min_tag_length = min_tag_length 

135 

136 @property 

137 def tag(self) -> bytes | None: 

138 return self._tag 

139 

140 @property 

141 def initialization_vector(self) -> utils.Buffer: 

142 return self._initialization_vector 

143 

144 def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: 

145 _check_aes_key_length(self, algorithm) 

146 if not isinstance(algorithm, BlockCipherAlgorithm): 

147 raise UnsupportedAlgorithm( 

148 "GCM requires a block cipher algorithm", 

149 _Reasons.UNSUPPORTED_CIPHER, 

150 ) 

151 block_size_bytes = algorithm.block_size // 8 

152 if self._tag is not None and len(self._tag) > block_size_bytes: 

153 raise ValueError( 

154 f"Authentication tag cannot be more than {block_size_bytes} " 

155 "bytes." 

156 ) 

157 

158 

159utils.deprecated( 

160 OFB, 

161 __name__, 

162 "OFB has been moved to " 

163 "cryptography.hazmat.decrepit.ciphers.modes.OFB and " 

164 "will be removed from " 

165 "cryptography.hazmat.primitives.ciphers.modes in 49.0.0.", 

166 utils.DeprecatedIn47, 

167 name="OFB", 

168) 

169 

170 

171utils.deprecated( 

172 CFB, 

173 __name__, 

174 "CFB has been moved to " 

175 "cryptography.hazmat.decrepit.ciphers.modes.CFB and " 

176 "will be removed from " 

177 "cryptography.hazmat.primitives.ciphers.modes in 49.0.0.", 

178 utils.DeprecatedIn47, 

179 name="CFB", 

180) 

181 

182 

183utils.deprecated( 

184 CFB8, 

185 __name__, 

186 "CFB8 has been moved to " 

187 "cryptography.hazmat.decrepit.ciphers.modes.CFB8 and " 

188 "will be removed from " 

189 "cryptography.hazmat.primitives.ciphers.modes in 49.0.0.", 

190 utils.DeprecatedIn47, 

191 name="CFB8", 

192)