prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  scapy.layers.tls.crypto.hkdf.TLS13_HKDF crashes when cryptography module is missing
  ### Brief description
  
  scapy.layers.tls.crypto.hkdf.TLS13_HKDF crashes in multiple environments
  
  ### Scapy version
  
  2.5.0
  
  ### Python version
  
  3.11.2
  
  ### Operating system
  
  macOS Ventura 13.3.1 (with M1 chip)
  
  ### Additional environment information
  
  _No response_
  
  ### How to reproduce
  
  ```
  $ python --version
  Python 3.11.2
  $ pip install scapy
  $ pip show scapy
  Name: scapy
  Version: 2.5.0
  ...
  $ python
  Python 3.11.2 (main, Feb 16 2023, 02:55:59) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin
  Type "help", "copyright", "credits" or "license" for more information.
  >>> from scapy.layers.tls.crypto.hkdf import TLS13_HKDF
  >>> TLS13_HKDF("sha256")
  ```
  
  We can also reproduce from the default python docker image:
  ```
  $ docker run -it --entrypoint bash python:latest
  # pip install scapy
  # python
  >>> from scapy.layers.tls.crypto.hkdf import TLS13_HKDF
  >>> TLS13_HKDF("sha256")
  ```
  
  ### Actual result
  
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/opt/homebrew/lib/python3.11/site-packages/scapy/layers/tls/crypto/hkdf.py", line 23, in __init__
      self.hash = _get_hash(hash_name)
                  ^^^^^^^^^^^^^^^^^^^^
  TypeError: 'NoneType' object is not callable
  
  ### Expected result
  
  <scapy.layers.tls.crypto.hkdf.TLS13_HKDF object at 0x...>
  
  ### Related resources
  
  _No response_
  
  </issue>
  <code>
  [start of scapy/layers/tls/crypto/hkdf.py]
  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) 2017 Maxence Tury
  5 
  6 """
  7 Stateless HKDF for TLS 1.3.
  8 """
  9 
  10 import struct
  11 
  12 from scapy.config import conf
  13 from scapy.layers.tls.crypto.pkcs1 import _get_hash
  14 
  15 if conf.crypto_valid:
  16     from cryptography.hazmat.backends import default_backend
  17     from cryptography.hazmat.primitives.kdf.hkdf import HKDF, HKDFExpand
  18     from cryptography.hazmat.primitives.hashes import Hash
  19     from cryptography.hazmat.primitives.hmac import HMAC
  20 
  21 
  22 class TLS13_HKDF(object):
  23     def __init__(self, hash_name="sha256"):
  24         self.hash = _get_hash(hash_name)
  25 
  26     def extract(self, salt, ikm):
  27         h = self.hash
  28         hkdf = HKDF(h, h.digest_size, salt, None, default_backend())
  29         if ikm is None:
  30             ikm = b"\x00" * h.digest_size
  31         return hkdf._extract(ikm)
  32 
  33     def expand(self, prk, info, L):
  34         h = self.hash
  35         hkdf = HKDFExpand(h, L, info, default_backend())
  36         return hkdf.derive(prk)
  37 
  38     def expand_label(self, secret, label, hash_value, length):
  39         hkdf_label = struct.pack("!H", length)
  40         hkdf_label += struct.pack("B", 6 + len(label))
  41         hkdf_label += b"tls13 "
  42         hkdf_label += label
  43         hkdf_label += struct.pack("B", len(hash_value))
  44         hkdf_label += hash_value
  45         return self.expand(secret, hkdf_label, length)
  46 
  47     def derive_secret(self, secret, label, messages):
  48         h = Hash(self.hash, backend=default_backend())
  49         h.update(messages)
  50         hash_messages = h.finalize()
  51         hash_len = self.hash.digest_size
  52         return self.expand_label(secret, label, hash_messages, hash_len)
  53 
  54     def compute_verify_data(self, basekey, handshake_context):
  55         hash_len = self.hash.digest_size
  56         finished_key = self.expand_label(basekey, b"finished", b"", hash_len)
  57 
  58         h = Hash(self.hash, backend=default_backend())
  59         h.update(handshake_context)
  60         hash_value = h.finalize()
  61 
  62         hm = HMAC(finished_key, self.hash, default_backend())
  63         hm.update(hash_value)
  64         return hm.finalize()
  65
  [end of scapy/layers/tls/crypto/hkdf.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/scapy/layers/tls/crypto/hkdf.py b/scapy/layers/tls/crypto/hkdf.py
  --- a/scapy/layers/tls/crypto/hkdf.py
  +++ b/scapy/layers/tls/crypto/hkdf.py
  @@ -9,7 +9,7 @@
   
   import struct
   
  -from scapy.config import conf
  +from scapy.config import conf, crypto_validator
   from scapy.layers.tls.crypto.pkcs1 import _get_hash
   
   if conf.crypto_valid:
  @@ -20,9 +20,11 @@
   
   
   class TLS13_HKDF(object):
  +    @crypto_validator
       def __init__(self, hash_name="sha256"):
           self.hash = _get_hash(hash_name)
   
  +    @crypto_validator
       def extract(self, salt, ikm):
           h = self.hash
           hkdf = HKDF(h, h.digest_size, salt, None, default_backend())
  @@ -30,11 +32,13 @@
               ikm = b"\x00" * h.digest_size
           return hkdf._extract(ikm)
   
  +    @crypto_validator
       def expand(self, prk, info, L):
           h = self.hash
           hkdf = HKDFExpand(h, L, info, default_backend())
           return hkdf.derive(prk)
   
  +    @crypto_validator
       def expand_label(self, secret, label, hash_value, length):
           hkdf_label = struct.pack("!H", length)
           hkdf_label += struct.pack("B", 6 + len(label))
  @@ -44,6 +48,7 @@
           hkdf_label += hash_value
           return self.expand(secret, hkdf_label, length)
   
  +    @crypto_validator
       def derive_secret(self, secret, label, messages):
           h = Hash(self.hash, backend=default_backend())
           h.update(messages)
  @@ -51,6 +56,7 @@
           hash_len = self.hash.digest_size
           return self.expand_label(secret, label, hash_messages, hash_len)
   
  +    @crypto_validator
       def compute_verify_data(self, basekey, handshake_context):
           hash_len = self.hash.digest_size
           finished_key = self.expand_label(basekey, b"finished", b"", hash_len)
  
verification_info: {"golden_diff": "diff --git a/scapy/layers/tls/crypto/hkdf.py b/scapy/layers/tls/crypto/hkdf.py\n--- a/scapy/layers/tls/crypto/hkdf.py\n+++ b/scapy/layers/tls/crypto/hkdf.py\n@@ -9,7 +9,7 @@\n \n import struct\n \n-from scapy.config import conf\n+from scapy.config import conf, crypto_validator\n from scapy.layers.tls.crypto.pkcs1 import _get_hash\n \n if conf.crypto_valid:\n@@ -20,9 +20,11 @@\n \n \n class TLS13_HKDF(object):\n+    @crypto_validator\n     def __init__(self, hash_name=\"sha256\"):\n         self.hash = _get_hash(hash_name)\n \n+    @crypto_validator\n     def extract(self, salt, ikm):\n         h = self.hash\n         hkdf = HKDF(h, h.digest_size, salt, None, default_backend())\n@@ -30,11 +32,13 @@\n             ikm = b\"\\x00\" * h.digest_size\n         return hkdf._extract(ikm)\n \n+    @crypto_validator\n     def expand(self, prk, info, L):\n         h = self.hash\n         hkdf = HKDFExpand(h, L, info, default_backend())\n         return hkdf.derive(prk)\n \n+    @crypto_validator\n     def expand_label(self, secret, label, hash_value, length):\n         hkdf_label = struct.pack(\"!H\", length)\n         hkdf_label += struct.pack(\"B\", 6 + len(label))\n@@ -44,6 +48,7 @@\n         hkdf_label += hash_value\n         return self.expand(secret, hkdf_label, length)\n \n+    @crypto_validator\n     def derive_secret(self, secret, label, messages):\n         h = Hash(self.hash, backend=default_backend())\n         h.update(messages)\n@@ -51,6 +56,7 @@\n         hash_len = self.hash.digest_size\n         return self.expand_label(secret, label, hash_messages, hash_len)\n \n+    @crypto_validator\n     def compute_verify_data(self, basekey, handshake_context):\n         hash_len = self.hash.digest_size\n         finished_key = self.expand_label(basekey, b\"finished\", b\"\", hash_len)\n", "issue": "scapy.layers.tls.crypto.hkdf.TLS13_HKDF crashes when cryptography module is missing\n### Brief description\n\nscapy.layers.tls.crypto.hkdf.TLS13_HKDF crashes in multiple environments\n\n### Scapy version\n\n2.5.0\n\n### Python version\n\n3.11.2\n\n### Operating system\n\nmacOS Ventura 13.3.1 (with M1 chip)\n\n### Additional environment information\n\n_No response_\n\n### How to reproduce\n\n```\r\n$ python --version\r\nPython 3.11.2\r\n$ pip install scapy\r\n$ pip show scapy\r\nName: scapy\r\nVersion: 2.5.0\r\n...\r\n$ python\r\nPython 3.11.2 (main, Feb 16 2023, 02:55:59) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin\r\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\r\n>>> from scapy.layers.tls.crypto.hkdf import TLS13_HKDF\r\n>>> TLS13_HKDF(\"sha256\")\r\n```\r\n\r\nWe can also reproduce from the default python docker image:\r\n```\r\n$ docker run -it --entrypoint bash python:latest\r\n# pip install scapy\r\n# python\r\n>>> from scapy.layers.tls.crypto.hkdf import TLS13_HKDF\r\n>>> TLS13_HKDF(\"sha256\")\r\n```\n\n### Actual result\n\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/opt/homebrew/lib/python3.11/site-packages/scapy/layers/tls/crypto/hkdf.py\", line 23, in __init__\r\n    self.hash = _get_hash(hash_name)\r\n                ^^^^^^^^^^^^^^^^^^^^\r\nTypeError: 'NoneType' object is not callable\n\n### Expected result\n\n<scapy.layers.tls.crypto.hkdf.TLS13_HKDF object at 0x...>\n\n### Related resources\n\n_No response_\n", "before_files": [{"content": "# SPDX-License-Identifier: GPL-2.0-only\n# This file is part of Scapy\n# See https://scapy.net/ for more information\n# Copyright (C) 2017 Maxence Tury\n\n\"\"\"\nStateless HKDF for TLS 1.3.\n\"\"\"\n\nimport struct\n\nfrom scapy.config import conf\nfrom scapy.layers.tls.crypto.pkcs1 import _get_hash\n\nif conf.crypto_valid:\n    from cryptography.hazmat.backends import default_backend\n    from cryptography.hazmat.primitives.kdf.hkdf import HKDF, HKDFExpand\n    from cryptography.hazmat.primitives.hashes import Hash\n    from cryptography.hazmat.primitives.hmac import HMAC\n\n\nclass TLS13_HKDF(object):\n    def __init__(self, hash_name=\"sha256\"):\n        self.hash = _get_hash(hash_name)\n\n    def extract(self, salt, ikm):\n        h = self.hash\n        hkdf = HKDF(h, h.digest_size, salt, None, default_backend())\n        if ikm is None:\n            ikm = b\"\\x00\" * h.digest_size\n        return hkdf._extract(ikm)\n\n    def expand(self, prk, info, L):\n        h = self.hash\n        hkdf = HKDFExpand(h, L, info, default_backend())\n        return hkdf.derive(prk)\n\n    def expand_label(self, secret, label, hash_value, length):\n        hkdf_label = struct.pack(\"!H\", length)\n        hkdf_label += struct.pack(\"B\", 6 + len(label))\n        hkdf_label += b\"tls13 \"\n        hkdf_label += label\n        hkdf_label += struct.pack(\"B\", len(hash_value))\n        hkdf_label += hash_value\n        return self.expand(secret, hkdf_label, length)\n\n    def derive_secret(self, secret, label, messages):\n        h = Hash(self.hash, backend=default_backend())\n        h.update(messages)\n        hash_messages = h.finalize()\n        hash_len = self.hash.digest_size\n        return self.expand_label(secret, label, hash_messages, hash_len)\n\n    def compute_verify_data(self, basekey, handshake_context):\n        hash_len = self.hash.digest_size\n        finished_key = self.expand_label(basekey, b\"finished\", b\"\", hash_len)\n\n        h = Hash(self.hash, backend=default_backend())\n        h.update(handshake_context)\n        hash_value = h.finalize()\n\n        hm = HMAC(finished_key, self.hash, default_backend())\n        hm.update(hash_value)\n        return hm.finalize()\n", "path": "scapy/layers/tls/crypto/hkdf.py"}]}