Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/layers/tls/crypto/h_mac.py: 68%

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

71 statements  

1# SPDX-License-Identifier: GPL-2.0-only 

2# This file is part of Scapy 

3# See https://scapy.net/ for more information 

4# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard 

5# 2015, 2016 Maxence Tury 

6 

7""" 

8HMAC classes. 

9""" 

10 

11from scapy.config import conf 

12from scapy.layers.tls.crypto.hash import _tls_hash_algs 

13 

14if conf.crypto_valid: 

15 from cryptography.hazmat.backends import default_backend 

16 from cryptography.hazmat.primitives.hmac import HMAC 

17 

18_SSLv3_PAD1_MD5 = b"\x36" * 48 

19_SSLv3_PAD1_SHA1 = b"\x36" * 40 

20_SSLv3_PAD2_MD5 = b"\x5c" * 48 

21_SSLv3_PAD2_SHA1 = b"\x5c" * 40 

22 

23_tls_hmac_algs = {} 

24 

25 

26class _GenericHMACMetaclass(type): 

27 """ 

28 HMAC classes are automatically registered through this metaclass. 

29 Furthermore, their name attribute is extracted from their class name. 

30 

31 Note that, when used with TLS, the HMAC key length equates the output of 

32 the associated hash function (see RFC 5246, appendix C). 

33 Also, we do not need to instantiate the associated hash function. 

34 """ 

35 

36 def __new__(cls, hmac_name, bases, dct): 

37 hash_name = hmac_name[5:] # remove leading "Hmac_" 

38 if hmac_name != "_GenericHMAC": 

39 hash_alg = _tls_hash_algs[hash_name.lower()] 

40 dct["name"] = "HMAC-%s" % hash_name 

41 dct["hash_alg"] = hash_alg 

42 dct["hmac_len"] = hash_alg.hash_len 

43 dct["key_len"] = dct["hmac_len"] 

44 the_class = super(_GenericHMACMetaclass, cls).__new__( 

45 cls, hmac_name, bases, dct 

46 ) 

47 if hmac_name != "_GenericHMAC": 

48 _tls_hmac_algs[dct["name"]] = the_class 

49 return the_class 

50 

51 

52class HMACError(Exception): 

53 """ 

54 Raised when HMAC verification fails. 

55 """ 

56 

57 pass 

58 

59 

60class _GenericHMAC(metaclass=_GenericHMACMetaclass): 

61 def __init__(self, key=None): 

62 self.key = key or b"" 

63 

64 def digest(self, tbd): 

65 if self.key is None: 

66 raise HMACError 

67 hm = HMAC(self.key, self.hash_alg.hash_cls(), backend=default_backend()) 

68 hm.update(tbd) 

69 return hm.finalize() 

70 

71 def digest_sslv3(self, tbd): 

72 if self.key is None: 

73 raise HMACError 

74 

75 h = self.hash_alg() 

76 if h.name == "sha": 

77 pad1 = _SSLv3_PAD1_SHA1 

78 pad2 = _SSLv3_PAD2_SHA1 

79 elif h.name == "md5": 

80 pad1 = _SSLv3_PAD1_MD5 

81 pad2 = _SSLv3_PAD2_MD5 

82 else: 

83 raise HMACError("Provided hash does not work with SSLv3.") 

84 

85 return h.digest(self.key + pad2 + h.digest(self.key + pad1 + tbd)) 

86 

87 

88class Hmac_NULL(_GenericHMAC): 

89 hmac_len = 0 

90 key_len = 0 

91 

92 def digest(self, tbd): 

93 return b"" 

94 

95 def digest_sslv3(self, tbd): 

96 return b"" 

97 

98 

99class Hmac_MD4(_GenericHMAC): 

100 pass 

101 

102 

103class Hmac_MD5(_GenericHMAC): 

104 pass 

105 

106 

107class Hmac_SHA(_GenericHMAC): 

108 pass 

109 

110 

111class Hmac_SHA224(_GenericHMAC): 

112 pass 

113 

114 

115class Hmac_SHA256(_GenericHMAC): 

116 pass 

117 

118 

119class Hmac_SHA384(_GenericHMAC): 

120 pass 

121 

122 

123class Hmac_SHA512(_GenericHMAC): 

124 pass 

125 

126 

127def Hmac(key, hashtype): 

128 """ 

129 Return Hmac object from Hash object and key 

130 """ 

131 return _tls_hmac_algs[f"HMAC-{hashtype.name.upper()}"](key=key)