diff --git a/scripts/mbedtls_dev/crypto_data_tests.py b/scripts/mbedtls_dev/crypto_data_tests.py
new file mode 100644
index 0000000..99c4e3d
--- /dev/null
+++ b/scripts/mbedtls_dev/crypto_data_tests.py
@@ -0,0 +1,123 @@
+"""Generate test data for cryptographic mechanisms.
+This module is a work in progress, only implementing a few cases for now.
+"""
+
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import hashlib
+from typing import Callable, Dict, Iterator, List, Optional #pylint: disable=unused-import
+
+from . import crypto_knowledge
+from . import psa_information
+from . import test_case
+
+
+def psa_low_level_dependencies(*expressions: str) -> List[str]:
+    """Infer dependencies of a PSA low-level test case by looking for PSA_xxx symbols.
+    This function generates MBEDTLS_PSA_BUILTIN_xxx symbols.
+    """
+    high_level = psa_information.automatic_dependencies(*expressions)
+    for dep in high_level:
+        assert dep.startswith('PSA_WANT_')
+    return ['MBEDTLS_PSA_BUILTIN_' + dep[9:] for dep in high_level]
+
+
+class HashPSALowLevel:
+    """Generate test cases for the PSA low-level hash interface."""
+
+    def __init__(self, info: psa_information.Information) -> None:
+        self.info = info
+        base_algorithms = sorted(info.constructors.algorithms)
+        all_algorithms = \
+            [crypto_knowledge.Algorithm(expr)
+             for expr in info.constructors.generate_expressions(base_algorithms)]
+        self.algorithms = \
+            [alg
+             for alg in all_algorithms
+             if (not alg.is_wildcard and
+                 alg.can_do(crypto_knowledge.AlgorithmCategory.HASH))]
+
+    # CALCULATE[alg] = function to return the hash of its argument in hex
+    # TO-DO: implement the None entries with a third-party library, because
+    # hashlib might not have everything, depending on the Python version and
+    # the underlying OpenSSL. On Ubuntu 16.04, truncated sha512 and sha3/shake
+    # are not available. On Ubuntu 22.04, md2, md4 and ripemd160 are not
+    # available.
+    CALCULATE = {
+        'PSA_ALG_MD2': None,
+        'PSA_ALG_MD4': None,
+        'PSA_ALG_MD5': lambda data: hashlib.md5(data).hexdigest(),
+        'PSA_ALG_RIPEMD160': None, #lambda data: hashlib.new('ripdemd160').hexdigest()
+        'PSA_ALG_SHA_1': lambda data: hashlib.sha1(data).hexdigest(),
+        'PSA_ALG_SHA_224': lambda data: hashlib.sha224(data).hexdigest(),
+        'PSA_ALG_SHA_256': lambda data: hashlib.sha256(data).hexdigest(),
+        'PSA_ALG_SHA_384': lambda data: hashlib.sha384(data).hexdigest(),
+        'PSA_ALG_SHA_512': lambda data: hashlib.sha512(data).hexdigest(),
+        'PSA_ALG_SHA_512_224': None, #lambda data: hashlib.new('sha512_224').hexdigest()
+        'PSA_ALG_SHA_512_256': None, #lambda data: hashlib.new('sha512_256').hexdigest()
+        'PSA_ALG_SHA3_224': None, #lambda data: hashlib.sha3_224(data).hexdigest(),
+        'PSA_ALG_SHA3_256': None, #lambda data: hashlib.sha3_256(data).hexdigest(),
+        'PSA_ALG_SHA3_384': None, #lambda data: hashlib.sha3_384(data).hexdigest(),
+        'PSA_ALG_SHA3_512': None, #lambda data: hashlib.sha3_512(data).hexdigest(),
+        'PSA_ALG_SHAKE256_512': None, #lambda data: hashlib.shake_256(data).hexdigest(64),
+    } #typing: Optional[Dict[str, Callable[[bytes], str]]]
+
+    @staticmethod
+    def one_test_case(alg: crypto_knowledge.Algorithm,
+                      function: str, note: str,
+                      arguments: List[str]) -> test_case.TestCase:
+        """Construct one test case involving a hash."""
+        tc = test_case.TestCase()
+        tc.set_description('{}{} {}'
+                           .format(function,
+                                   ' ' + note if note else '',
+                                   alg.short_expression()))
+        tc.set_dependencies(psa_low_level_dependencies(alg.expression))
+        tc.set_function(function)
+        tc.set_arguments([alg.expression] +
+                         ['"{}"'.format(arg) for arg in arguments])
+        return tc
+
+    def test_cases_for_hash(self,
+                            alg: crypto_knowledge.Algorithm
+                            ) -> Iterator[test_case.TestCase]:
+        """Enumerate all test cases for one hash algorithm."""
+        calc = self.CALCULATE[alg.expression]
+        if calc is None:
+            return # not implemented yet
+
+        short = b'abc'
+        hash_short = calc(short)
+        long = (b'Hello, world. Here are 16 unprintable bytes: ['
+                b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a'
+                b'\x80\x81\x82\x83\xfe\xff]. '
+                b' This message was brought to you by a natural intelligence. '
+                b' If you can read this, good luck with your debugging!')
+        hash_long = calc(long)
+
+        yield self.one_test_case(alg, 'hash_empty', '', [calc(b'')])
+        yield self.one_test_case(alg, 'hash_valid_one_shot', '',
+                                 [short.hex(), hash_short])
+        for n in [0, 1, 64, len(long) - 1, len(long)]:
+            yield self.one_test_case(alg, 'hash_valid_multipart',
+                                     '{} + {}'.format(n, len(long) - n),
+                                     [long[:n].hex(), calc(long[:n]),
+                                      long[n:].hex(), hash_long])
+
+    def all_test_cases(self) -> Iterator[test_case.TestCase]:
+        """Enumerate all test cases for all hash algorithms."""
+        for alg in self.algorithms:
+            yield from self.test_cases_for_hash(alg)
