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

69 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 

11import hmac 

12 

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

14from scapy.compat import bytes_encode 

15 

16_SSLv3_PAD1_MD5 = b"\x36" * 48 

17_SSLv3_PAD1_SHA1 = b"\x36" * 40 

18_SSLv3_PAD2_MD5 = b"\x5c" * 48 

19_SSLv3_PAD2_SHA1 = b"\x5c" * 40 

20 

21_tls_hmac_algs = {} 

22 

23 

24class _GenericHMACMetaclass(type): 

25 """ 

26 HMAC classes are automatically registered through this metaclass. 

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

28 

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

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

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

32 """ 

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

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

35 if hmac_name != "_GenericHMAC": 

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

37 dct["hash_alg"] = _tls_hash_algs[hash_name] 

38 dct["hmac_len"] = _tls_hash_algs[hash_name].hash_len 

39 dct["key_len"] = dct["hmac_len"] 

40 the_class = super(_GenericHMACMetaclass, cls).__new__(cls, hmac_name, 

41 bases, dct) 

42 if hmac_name != "_GenericHMAC": 

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

44 return the_class 

45 

46 

47class HMACError(Exception): 

48 """ 

49 Raised when HMAC verification fails. 

50 """ 

51 pass 

52 

53 

54class _GenericHMAC(metaclass=_GenericHMACMetaclass): 

55 def __init__(self, key=None): 

56 if key is None: 

57 self.key = b"" 

58 else: 

59 self.key = bytes_encode(key) 

60 

61 def digest(self, tbd): 

62 if self.key is None: 

63 raise HMACError 

64 tbd = bytes_encode(tbd) 

65 return hmac.new(self.key, tbd, self.hash_alg.hash_cls).digest() 

66 

67 def digest_sslv3(self, tbd): 

68 if self.key is None: 

69 raise HMACError 

70 

71 h = self.hash_alg() 

72 if h.name == "SHA": 

73 pad1 = _SSLv3_PAD1_SHA1 

74 pad2 = _SSLv3_PAD2_SHA1 

75 elif h.name == "MD5": 

76 pad1 = _SSLv3_PAD1_MD5 

77 pad2 = _SSLv3_PAD2_MD5 

78 else: 

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

80 

81 return h.digest(self.key + pad2 + 

82 h.digest(self.key + pad1 + tbd)) 

83 

84 

85class Hmac_NULL(_GenericHMAC): 

86 hmac_len = 0 

87 key_len = 0 

88 

89 def digest(self, tbd): 

90 return b"" 

91 

92 def digest_sslv3(self, tbd): 

93 return b"" 

94 

95 

96class Hmac_MD4(_GenericHMAC): 

97 pass 

98 

99 

100class Hmac_MD5(_GenericHMAC): 

101 pass 

102 

103 

104class Hmac_SHA(_GenericHMAC): 

105 pass 

106 

107 

108class Hmac_SHA224(_GenericHMAC): 

109 pass 

110 

111 

112class Hmac_SHA256(_GenericHMAC): 

113 pass 

114 

115 

116class Hmac_SHA384(_GenericHMAC): 

117 pass 

118 

119 

120class Hmac_SHA512(_GenericHMAC): 

121 pass 

122 

123 

124def Hmac(key, hashtype): 

125 """ 

126 Return Hmac object from Hash object and key 

127 """ 

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