For convenience, the synopsis of the encoding method is given below; however, this section, [NIST-SP800-56A], and [RFC3394] are the normative sources of the definition. Obtain the authenticated recipient public key R Generate an ephemeral key pair {v
(cls, pk, *args)
| 1696 | |
| 1697 | @classmethod |
| 1698 | def encrypt(cls, pk, *args): |
| 1699 | """ |
| 1700 | For convenience, the synopsis of the encoding method is given below; |
| 1701 | however, this section, [NIST-SP800-56A], and [RFC3394] are the |
| 1702 | normative sources of the definition. |
| 1703 | |
| 1704 | Obtain the authenticated recipient public key R |
| 1705 | Generate an ephemeral key pair {v, V=vG} |
| 1706 | Compute the shared point S = vR; |
| 1707 | m = symm_alg_ID || session key || checksum || pkcs5_padding; |
| 1708 | curve_OID_len = (byte)len(curve_OID); |
| 1709 | Param = curve_OID_len || curve_OID || public_key_alg_ID || 03 |
| 1710 | || 01 || KDF_hash_ID || KEK_alg_ID for AESKeyWrap || "Anonymous |
| 1711 | Sender " || recipient_fingerprint; |
| 1712 | Z_len = the key size for the KEK_alg_ID used with AESKeyWrap |
| 1713 | Compute Z = KDF( S, Z_len, Param ); |
| 1714 | Compute C = AESKeyWrap( Z, m ) as per [RFC3394] |
| 1715 | VB = convert point V to the octet string |
| 1716 | Output (MPI(VB) || len(C) || C). |
| 1717 | |
| 1718 | The decryption is the inverse of the method given. Note that the |
| 1719 | recipient obtains the shared secret by calculating |
| 1720 | """ |
| 1721 | # *args should be: |
| 1722 | # - m |
| 1723 | # |
| 1724 | _m, = args |
| 1725 | |
| 1726 | # m may need to be PKCS5-padded |
| 1727 | padder = PKCS7(64).padder() |
| 1728 | m = padder.update(_m) + padder.finalize() |
| 1729 | |
| 1730 | km = pk.keymaterial |
| 1731 | ct = cls() |
| 1732 | |
| 1733 | # generate ephemeral key pair and keep public key in ct |
| 1734 | # use private key to compute the shared point "s" |
| 1735 | if km.oid == EllipticCurveOID.Curve25519: |
| 1736 | v = x25519.X25519PrivateKey.generate() |
| 1737 | x = v.public_key().public_bytes(encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw) |
| 1738 | ct.p = ECPoint.from_values(km.oid.key_size, ECPointFormat.Native, x) |
| 1739 | s = v.exchange(km.__pubkey__()) |
| 1740 | else: |
| 1741 | v = ec.generate_private_key(km.oid.curve(), default_backend()) |
| 1742 | x = MPI(v.public_key().public_numbers().x) |
| 1743 | y = MPI(v.public_key().public_numbers().y) |
| 1744 | ct.p = ECPoint.from_values(km.oid.key_size, ECPointFormat.Standard, x, y) |
| 1745 | s = v.exchange(ec.ECDH(), km.__pubkey__()) |
| 1746 | |
| 1747 | # derive the wrapping key |
| 1748 | z = km.kdf.derive_key(s, km.oid, PubKeyAlgorithm.ECDH, pk.fingerprint) |
| 1749 | |
| 1750 | # compute C |
| 1751 | ct.c = aes_key_wrap(z, m, default_backend()) |
| 1752 | |
| 1753 | return ct |
| 1754 | |
| 1755 | def decrypt(self, pk, *args): |
nothing calls this directly
no test coverage detected