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