|
1 | 1 | """Tests for COSE-HPKE test vectors from draft-ietf-cose-hpke-23 Appendix C.""" |
2 | 2 |
|
| 3 | +import os |
| 4 | + |
3 | 5 | import cbor2 |
4 | 6 | import pytest |
5 | 7 |
|
@@ -1619,3 +1621,95 @@ def test_encrypt0_vector(self, key_hex, ct_hex, external_aad, hpke_info): |
1619 | 1621 | ct = bytes.fromhex(ct_hex) |
1620 | 1622 | result = COSE.new().decode(ct, key, external_aad=external_aad, hpke_info=hpke_info) |
1621 | 1623 | assert result == b"hpke test payload" |
| 1624 | + |
| 1625 | + |
| 1626 | +# --- PSK vectors loaded from testvectors.txt --- |
| 1627 | + |
| 1628 | +VECTORS_PATH = os.path.join(os.path.dirname(__file__), "vectors", "testvectors.txt") |
| 1629 | + |
| 1630 | +PLAINTEXT = b"hpke test payload" |
| 1631 | + |
| 1632 | +PSK = bytes.fromhex("0247fd33b913760fa1fa51e1892d9f307fbe65eb171e8132c2af18555a738b82") |
| 1633 | + |
| 1634 | +EXT_AAD = b"external-aad" |
| 1635 | +EXT_INFO = b"external-info" |
| 1636 | +EXT_HPKE_AAD = b"external-hpke-aad" |
| 1637 | + |
| 1638 | + |
| 1639 | +def _parse_psk_vectors(): |
| 1640 | + """Parse testvectors.txt and return KE+PSK and Encrypt0+PSK vectors.""" |
| 1641 | + with open(VECTORS_PATH) as f: |
| 1642 | + lines = f.readlines() |
| 1643 | + |
| 1644 | + ke_psk = [] |
| 1645 | + e0_psk = [] |
| 1646 | + |
| 1647 | + current_key = None |
| 1648 | + i = 0 |
| 1649 | + while i < len(lines): |
| 1650 | + line = lines[i].rstrip("\n") |
| 1651 | + i += 1 |
| 1652 | + |
| 1653 | + if "COSE_Key" in line: |
| 1654 | + idx = line.rfind(": ") |
| 1655 | + if idx >= 0: |
| 1656 | + current_key = line[idx + 2 :].strip() |
| 1657 | + continue |
| 1658 | + |
| 1659 | + if "KE+PSK with" in line: |
| 1660 | + desc = line |
| 1661 | + while i < len(lines): |
| 1662 | + ct_line = lines[i].rstrip("\n") |
| 1663 | + i += 1 |
| 1664 | + if ct_line.startswith("Ciphertext: "): |
| 1665 | + ct_hex = ct_line[len("Ciphertext: ") :] |
| 1666 | + break |
| 1667 | + ext_aad = EXT_AAD if "external aad" in desc else b"" |
| 1668 | + extra_info = EXT_INFO if "external info" in desc else b"" |
| 1669 | + hpke_aad = EXT_HPKE_AAD if "external hpke aad" in desc else b"" |
| 1670 | + ke_psk.append((current_key, ct_hex, ext_aad, extra_info, hpke_aad)) |
| 1671 | + |
| 1672 | + elif "Encrypt0+PSK with" in line: |
| 1673 | + desc = line |
| 1674 | + while i < len(lines): |
| 1675 | + ct_line = lines[i].rstrip("\n") |
| 1676 | + i += 1 |
| 1677 | + if ct_line.startswith("Ciphertext: "): |
| 1678 | + ct_hex = ct_line[len("Ciphertext: ") :] |
| 1679 | + break |
| 1680 | + ext_aad = EXT_AAD if "external aad" in desc else b"" |
| 1681 | + hpke_info = EXT_INFO if "external info" in desc else b"" |
| 1682 | + e0_psk.append((current_key, ct_hex, ext_aad, hpke_info)) |
| 1683 | + |
| 1684 | + return ke_psk, e0_psk |
| 1685 | + |
| 1686 | + |
| 1687 | +_KE_PSK_VECTORS, _E0_PSK_VECTORS = _parse_psk_vectors() |
| 1688 | + |
| 1689 | + |
| 1690 | +class TestCOSEHPKEKEPSKVectors: |
| 1691 | + """Test vectors for COSE-HPKE Key Encryption with PSK (COSE_Encrypt).""" |
| 1692 | + |
| 1693 | + @pytest.mark.parametrize( |
| 1694 | + "key_hex, ct_hex, external_aad, extra_info, hpke_aad", |
| 1695 | + _KE_PSK_VECTORS, |
| 1696 | + ) |
| 1697 | + def test_ke_psk_vector(self, key_hex, ct_hex, external_aad, extra_info, hpke_aad): |
| 1698 | + key = COSEKey.new(cbor2.loads(bytes.fromhex(key_hex))) |
| 1699 | + ct = bytes.fromhex(ct_hex) |
| 1700 | + result = COSE.new().decode(ct, key, external_aad=external_aad, extra_info=extra_info, hpke_aad=hpke_aad, hpke_psk=PSK) |
| 1701 | + assert result == PLAINTEXT |
| 1702 | + |
| 1703 | + |
| 1704 | +class TestCOSEHPKEEncrypt0PSKVectors: |
| 1705 | + """Test vectors for COSE-HPKE Integrated Encryption with PSK (COSE_Encrypt0).""" |
| 1706 | + |
| 1707 | + @pytest.mark.parametrize( |
| 1708 | + "key_hex, ct_hex, external_aad, hpke_info", |
| 1709 | + _E0_PSK_VECTORS, |
| 1710 | + ) |
| 1711 | + def test_encrypt0_psk_vector(self, key_hex, ct_hex, external_aad, hpke_info): |
| 1712 | + key = COSEKey.new(cbor2.loads(bytes.fromhex(key_hex))) |
| 1713 | + ct = bytes.fromhex(ct_hex) |
| 1714 | + result = COSE.new().decode(ct, key, external_aad=external_aad, hpke_info=hpke_info, hpke_psk=PSK) |
| 1715 | + assert result == PLAINTEXT |
0 commit comments