| 881 | |
| 882 | |
| 883 | def load_nist_ccm_vectors(vector_data: typing.Iterable[str]) -> list[dict]: |
| 884 | test_data: dict[str, typing.Any] = {} |
| 885 | section_data: dict[str, typing.Any] = {} |
| 886 | global_data: dict[str, typing.Any] = {} |
| 887 | new_section = False |
| 888 | data = [] |
| 889 | |
| 890 | for line in vector_data: |
| 891 | line = line.strip() |
| 892 | |
| 893 | # Blank lines and comments should be ignored |
| 894 | if not line or line.startswith("#"): |
| 895 | continue |
| 896 | |
| 897 | # Some of the CCM vectors have global values for this. They are always |
| 898 | # at the top before the first section header (see: VADT, VNT, VPT) |
| 899 | if line.startswith(("Alen", "Plen", "Nlen", "Tlen")): |
| 900 | name, value = (c.strip() for c in line.split("=")) |
| 901 | global_data[name.lower()] = int(value) |
| 902 | continue |
| 903 | |
| 904 | # section headers contain length data we might care about |
| 905 | if line.startswith("["): |
| 906 | new_section = True |
| 907 | section_data = {} |
| 908 | section = line[1:-1] |
| 909 | items = [c.strip() for c in section.split(",")] |
| 910 | for item in items: |
| 911 | name, value = (c.strip() for c in item.split("=")) |
| 912 | section_data[name.lower()] = int(value) |
| 913 | continue |
| 914 | |
| 915 | name, value = (c.strip() for c in line.split("=")) |
| 916 | |
| 917 | if name.lower() in ("key", "nonce") and new_section: |
| 918 | section_data[name.lower()] = value.encode("ascii") |
| 919 | continue |
| 920 | |
| 921 | new_section = False |
| 922 | |
| 923 | # Payload is sometimes special because these vectors are absurd. Each |
| 924 | # example may or may not have a payload. If it does not then the |
| 925 | # previous example's payload should be used. We accomplish this by |
| 926 | # writing it into the section_data. Because we update each example |
| 927 | # with the section data it will be overwritten if a new payload value |
| 928 | # is present. NIST should be ashamed of their vector creation. |
| 929 | if name.lower() == "payload": |
| 930 | section_data[name.lower()] = value.encode("ascii") |
| 931 | |
| 932 | # Result is a special token telling us if the test should pass/fail. |
| 933 | # This is only present in the DVPT CCM tests |
| 934 | if name.lower() == "result": |
| 935 | if value.lower() == "pass": |
| 936 | test_data["fail"] = False |
| 937 | else: |
| 938 | test_data["fail"] = True |
| 939 | continue |
| 940 | |