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, 2017 Maxence Tury 6 7""" 8TLS Pseudorandom Function. 9""" 10 11from scapy.error import warning 12from scapy.utils import strxor 13 14from scapy.layers.tls.crypto.hash import _tls_hash_algs 15from scapy.layers.tls.crypto.h_mac import _tls_hmac_algs 16from scapy.compat import bytes_encode 17 18 19# Data expansion functions 20 21def _tls_P_hash(secret, seed, req_len, hm): 22 """ 23 Provides the implementation of P_hash function defined in 24 section 5 of RFC 4346 (and section 5 of RFC 5246). Two 25 parameters have been added (hm and req_len): 26 27 - secret : the key to be used. If RFC 4868 is to be believed, 28 the length must match hm.key_len. Actually, 29 python hmac takes care of formatting every key. 30 - seed : the seed to be used. 31 - req_len : the length of data to be generated by iterating 32 the specific HMAC function (hm). This prevents 33 multiple calls to the function. 34 - hm : the hmac function class to use for iteration (either 35 Hmac_MD5 or Hmac_SHA1 in TLS <= 1.1 or 36 Hmac_SHA256 or Hmac_SHA384 in TLS 1.2) 37 """ 38 hash_len = hm.hash_alg.hash_len 39 n = (req_len + hash_len - 1) // hash_len 40 seed = bytes_encode(seed) 41 42 res = b"" 43 a = hm(secret).digest(seed) # A(1) 44 45 while n > 0: 46 res += hm(secret).digest(a + seed) 47 a = hm(secret).digest(a) 48 n -= 1 49 50 return res[:req_len] 51 52 53def _tls_P_MD5(secret, seed, req_len): 54 return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-MD5"]) 55 56 57def _tls_P_SHA1(secret, seed, req_len): 58 return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-SHA"]) 59 60 61def _tls_P_SHA256(secret, seed, req_len): 62 return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-SHA256"]) 63 64 65def _tls_P_SHA384(secret, seed, req_len): 66 return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-SHA384"]) 67 68 69def _tls_P_SHA512(secret, seed, req_len): 70 return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-SHA512"]) 71 72 73# PRF functions, according to the protocol version 74 75def _sslv2_PRF(secret, seed, req_len): 76 hash_md5 = _tls_hash_algs["MD5"]() 77 rounds = (req_len + hash_md5.hash_len - 1) // hash_md5.hash_len 78 79 res = b"" 80 if rounds == 1: 81 res += hash_md5.digest(secret + seed) 82 else: 83 r = 0 84 while r < rounds: 85 label = str(r).encode("utf8") 86 res += hash_md5.digest(secret + label + seed) 87 r += 1 88 89 return res[:req_len] 90 91 92def _ssl_PRF(secret, seed, req_len): 93 """ 94 Provides the implementation of SSLv3 PRF function: 95 96 SSLv3-PRF(secret, seed) = 97 MD5(secret || SHA-1("A" || secret || seed)) || 98 MD5(secret || SHA-1("BB" || secret || seed)) || 99 MD5(secret || SHA-1("CCC" || secret || seed)) || ... 100 101 req_len should not be more than 26 x 16 = 416. 102 """ 103 if req_len > 416: 104 warning("_ssl_PRF() is not expected to provide more than 416 bytes") 105 return "" 106 107 d = [b"A", b"B", b"C", b"D", b"E", b"F", b"G", b"H", b"I", b"J", b"K", b"L", # noqa: E501 108 b"M", b"N", b"O", b"P", b"Q", b"R", b"S", b"T", b"U", b"V", b"W", b"X", # noqa: E501 109 b"Y", b"Z"] 110 res = b"" 111 hash_sha1 = _tls_hash_algs["SHA"]() 112 hash_md5 = _tls_hash_algs["MD5"]() 113 rounds = (req_len + hash_md5.hash_len - 1) // hash_md5.hash_len 114 115 for i in range(rounds): 116 label = d[i] * (i + 1) 117 tmp = hash_sha1.digest(label + secret + seed) 118 res += hash_md5.digest(secret + tmp) 119 120 return res[:req_len] 121 122 123def _tls_PRF(secret, label, seed, req_len): 124 """ 125 Provides the implementation of TLS PRF function as defined in 126 section 5 of RFC 4346: 127 128 PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR 129 P_SHA-1(S2, label + seed) 130 131 Parameters are: 132 133 - secret: the secret used by the HMAC in the 2 expansion 134 functions (S1 and S2 are the halves of this secret). 135 - label: specific label as defined in various sections of the RFC 136 depending on the use of the generated PRF keystream 137 - seed: the seed used by the expansion functions. 138 - req_len: amount of keystream to be generated 139 """ 140 tmp_len = (len(secret) + 1) // 2 141 S1 = secret[:tmp_len] 142 S2 = secret[-tmp_len:] 143 144 a1 = _tls_P_MD5(S1, label + seed, req_len) 145 a2 = _tls_P_SHA1(S2, label + seed, req_len) 146 147 return strxor(a1, a2) 148 149 150def _tls12_SHA256PRF(secret, label, seed, req_len): 151 """ 152 Provides the implementation of TLS 1.2 PRF function as 153 defined in section 5 of RFC 5246: 154 155 PRF(secret, label, seed) = P_SHA256(secret, label + seed) 156 157 Parameters are: 158 159 - secret: the secret used by the HMAC in the 2 expansion 160 functions (S1 and S2 are the halves of this secret). 161 - label: specific label as defined in various sections of the RFC 162 depending on the use of the generated PRF keystream 163 - seed: the seed used by the expansion functions. 164 - req_len: amount of keystream to be generated 165 """ 166 return _tls_P_SHA256(secret, label + seed, req_len) 167 168 169def _tls12_SHA384PRF(secret, label, seed, req_len): 170 return _tls_P_SHA384(secret, label + seed, req_len) 171 172 173def _tls12_SHA512PRF(secret, label, seed, req_len): 174 return _tls_P_SHA512(secret, label + seed, req_len) 175 176 177class PRF(object): 178 """ 179 The PRF used by SSL/TLS varies based on the version of the protocol and 180 (for TLS 1.2) possibly the Hash algorithm of the negotiated cipher suite. 181 The various uses of the PRF (key derivation, computation of verify_data, 182 computation of pre_master_secret values) for the different versions of the 183 protocol also changes. In order to abstract those elements, the common 184 _tls_PRF() object is provided. It is expected to be initialised in the 185 context of the connection state using the tls_version and the cipher suite. 186 """ 187 188 def __init__(self, hash_name="SHA256", tls_version=0x0303): 189 self.tls_version = tls_version 190 self.hash_name = hash_name 191 192 if tls_version < 0x0300: # SSLv2 193 self.prf = _sslv2_PRF 194 elif tls_version == 0x0300: # SSLv3 195 self.prf = _ssl_PRF 196 elif (tls_version == 0x0301 or # TLS 1.0 197 tls_version == 0x0302): # TLS 1.1 198 self.prf = _tls_PRF 199 elif tls_version == 0x0303: # TLS 1.2 200 if hash_name == "SHA384": 201 self.prf = _tls12_SHA384PRF 202 elif hash_name == "SHA512": 203 self.prf = _tls12_SHA512PRF 204 else: 205 if hash_name in ["MD5", "SHA"]: 206 self.hash_name = "SHA256" 207 self.prf = _tls12_SHA256PRF 208 else: 209 warning("Unknown TLS version") 210 211 def compute_master_secret(self, pre_master_secret, client_random, 212 server_random, extms=False, handshake_hash=None): 213 """ 214 Return the 48-byte master_secret, computed from pre_master_secret, 215 client_random and server_random. See RFC 5246, section 6.3. 216 Supports Extended Master Secret Derivation, see RFC 7627 217 """ 218 seed = client_random + server_random 219 label = b'master secret' 220 221 if extms is True and handshake_hash is not None: 222 seed = handshake_hash 223 label = b'extended master secret' 224 225 if self.tls_version < 0x0300: 226 return None 227 elif self.tls_version == 0x0300: 228 return self.prf(pre_master_secret, seed, 48) 229 else: 230 return self.prf(pre_master_secret, label, seed, 48) 231 232 def derive_key_block(self, master_secret, server_random, 233 client_random, req_len): 234 """ 235 Perform the derivation of master_secret into a key_block of req_len 236 requested length. See RFC 5246, section 6.3. 237 """ 238 seed = server_random + client_random 239 if self.tls_version <= 0x0300: 240 return self.prf(master_secret, seed, req_len) 241 else: 242 return self.prf(master_secret, b"key expansion", seed, req_len) 243 244 def compute_verify_data(self, con_end, read_or_write, 245 handshake_msg, master_secret): 246 """ 247 Return verify_data based on handshake messages, connection end, 248 master secret, and read_or_write position. See RFC 5246, section 7.4.9. 249 250 Every TLS 1.2 cipher suite has a verify_data of length 12. Note also:: 251 252 "This PRF with the SHA-256 hash function is used for all cipher 253 suites defined in this document and in TLS documents published 254 prior to this document when TLS 1.2 is negotiated." 255 256 Cipher suites using SHA-384 were defined later on. 257 """ 258 if self.tls_version < 0x0300: 259 return None 260 elif self.tls_version == 0x0300: 261 262 if read_or_write == "write": 263 d = {"client": b"CLNT", "server": b"SRVR"} 264 else: 265 d = {"client": b"SRVR", "server": b"CLNT"} 266 label = d[con_end] 267 268 sslv3_md5_pad1 = b"\x36" * 48 269 sslv3_md5_pad2 = b"\x5c" * 48 270 sslv3_sha1_pad1 = b"\x36" * 40 271 sslv3_sha1_pad2 = b"\x5c" * 40 272 273 md5 = _tls_hash_algs["MD5"]() 274 sha1 = _tls_hash_algs["SHA"]() 275 276 md5_hash = md5.digest(master_secret + sslv3_md5_pad2 + 277 md5.digest(handshake_msg + label + 278 master_secret + sslv3_md5_pad1)) 279 sha1_hash = sha1.digest(master_secret + sslv3_sha1_pad2 + 280 sha1.digest(handshake_msg + label + 281 master_secret + sslv3_sha1_pad1)) # noqa: E501 282 verify_data = md5_hash + sha1_hash 283 284 else: 285 286 if read_or_write == "write": 287 d = {"client": "client", "server": "server"} 288 else: 289 d = {"client": "server", "server": "client"} 290 label = ("%s finished" % d[con_end]).encode() 291 292 if self.tls_version <= 0x0302: 293 s1 = _tls_hash_algs["MD5"]().digest(handshake_msg) 294 s2 = _tls_hash_algs["SHA"]().digest(handshake_msg) 295 verify_data = self.prf(master_secret, label, s1 + s2, 12) 296 else: 297 h = _tls_hash_algs[self.hash_name]() 298 s = h.digest(handshake_msg) 299 verify_data = self.prf(master_secret, label, s, 12) 300 301 return verify_data 302 303 def postprocess_key_for_export(self, key, client_random, server_random, 304 con_end, read_or_write, req_len): 305 """ 306 Postprocess cipher key for EXPORT ciphersuite, i.e. weakens it. 307 An export key generation example is given in section 6.3.1 of RFC 2246. 308 See also page 86 of EKR's book. 309 """ 310 s = con_end + read_or_write 311 s = (s == "clientwrite" or s == "serverread") 312 313 if self.tls_version < 0x0300: 314 return None 315 elif self.tls_version == 0x0300: 316 if s: 317 tbh = key + client_random + server_random 318 else: 319 tbh = key + server_random + client_random 320 export_key = _tls_hash_algs["MD5"]().digest(tbh)[:req_len] 321 else: 322 if s: 323 tag = b"client write key" 324 else: 325 tag = b"server write key" 326 export_key = self.prf(key, 327 tag, 328 client_random + server_random, 329 req_len) 330 return export_key 331 332 def generate_iv_for_export(self, client_random, server_random, 333 con_end, read_or_write, req_len): 334 """ 335 Generate IV for EXPORT ciphersuite, i.e. weakens it. 336 An export IV generation example is given in section 6.3.1 of RFC 2246. 337 See also page 86 of EKR's book. 338 """ 339 s = con_end + read_or_write 340 s = (s == "clientwrite" or s == "serverread") 341 342 if self.tls_version < 0x0300: 343 return None 344 elif self.tls_version == 0x0300: 345 if s: 346 tbh = client_random + server_random 347 else: 348 tbh = server_random + client_random 349 iv = _tls_hash_algs["MD5"]().digest(tbh)[:req_len] 350 else: 351 iv_block = self.prf("", 352 b"IV block", 353 client_random + server_random, 354 2 * req_len) 355 if s: 356 iv = iv_block[:req_len] 357 else: 358 iv = iv_block[req_len:] 359 return iv 360