Skip to content

Commit 83b4c3d

Browse files
committed
Convert ed448 to Rust
1 parent f5c750d commit 83b4c3d

File tree

8 files changed

+231
-228
lines changed

8 files changed

+231
-228
lines changed

src/cryptography/hazmat/backends/openssl/backend.py

Lines changed: 13 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@
3030
_EllipticCurvePrivateKey,
3131
_EllipticCurvePublicKey,
3232
)
33-
from cryptography.hazmat.backends.openssl.ed448 import (
34-
_ED448_KEY_SIZE,
35-
_Ed448PrivateKey,
36-
_Ed448PublicKey,
37-
)
3833
from cryptography.hazmat.backends.openssl.hashes import _HashContext
3934
from cryptography.hazmat.backends.openssl.hmac import _HMACContext
4035
from cryptography.hazmat.backends.openssl.poly1305 import (
@@ -651,7 +646,9 @@ def _evp_pkey_to_private_key(
651646
)
652647
elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None):
653648
# EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL
654-
return _Ed448PrivateKey(self, evp_pkey)
649+
return rust_openssl.ed448.private_key_from_ptr(
650+
int(self._ffi.cast("uintptr_t", evp_pkey))
651+
)
655652
else:
656653
raise UnsupportedAlgorithm("Unsupported key type.")
657654

@@ -714,7 +711,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes:
714711
)
715712
elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None):
716713
# EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL
717-
return _Ed448PublicKey(self, evp_pkey)
714+
return rust_openssl.ed448.public_key_from_ptr(
715+
int(self._ffi.cast("uintptr_t", evp_pkey))
716+
)
718717
else:
719718
raise UnsupportedAlgorithm("Unsupported key type.")
720719

@@ -1503,12 +1502,9 @@ def _private_key_bytes(
15031502
write_bio = self._lib.PEM_write_bio_RSAPrivateKey
15041503
elif key_type == self._lib.EVP_PKEY_DSA:
15051504
write_bio = self._lib.PEM_write_bio_DSAPrivateKey
1506-
elif key_type == self._lib.EVP_PKEY_EC:
1507-
write_bio = self._lib.PEM_write_bio_ECPrivateKey
15081505
else:
1509-
raise ValueError(
1510-
"Unsupported key type for TraditionalOpenSSL"
1511-
)
1506+
assert key_type == self._lib.EVP_PKEY_EC
1507+
write_bio = self._lib.PEM_write_bio_ECPrivateKey
15121508
return self._private_key_bytes_via_bio(
15131509
write_bio, cdata, password
15141510
)
@@ -1523,12 +1519,9 @@ def _private_key_bytes(
15231519
write_bio = self._lib.i2d_RSAPrivateKey_bio
15241520
elif key_type == self._lib.EVP_PKEY_EC:
15251521
write_bio = self._lib.i2d_ECPrivateKey_bio
1526-
elif key_type == self._lib.EVP_PKEY_DSA:
1527-
write_bio = self._lib.i2d_DSAPrivateKey_bio
15281522
else:
1529-
raise ValueError(
1530-
"Unsupported key type for TraditionalOpenSSL"
1531-
)
1523+
assert key_type == self._lib.EVP_PKEY_DSA
1524+
write_bio = self._lib.i2d_DSAPrivateKey_bio
15321525
return self._bio_func_output(write_bio, cdata)
15331526

15341527
raise ValueError("Unsupported encoding for TraditionalOpenSSL")
@@ -1817,19 +1810,6 @@ def x25519_load_private_bytes(
18171810
) -> x25519.X25519PrivateKey:
18181811
return rust_openssl.x25519.from_private_bytes(data)
18191812

1820-
def _evp_pkey_keygen_gc(self, nid):
1821-
evp_pkey_ctx = self._lib.EVP_PKEY_CTX_new_id(nid, self._ffi.NULL)
1822-
self.openssl_assert(evp_pkey_ctx != self._ffi.NULL)
1823-
evp_pkey_ctx = self._ffi.gc(evp_pkey_ctx, self._lib.EVP_PKEY_CTX_free)
1824-
res = self._lib.EVP_PKEY_keygen_init(evp_pkey_ctx)
1825-
self.openssl_assert(res == 1)
1826-
evp_ppkey = self._ffi.new("EVP_PKEY **")
1827-
res = self._lib.EVP_PKEY_keygen(evp_pkey_ctx, evp_ppkey)
1828-
self.openssl_assert(res == 1)
1829-
self.openssl_assert(evp_ppkey[0] != self._ffi.NULL)
1830-
evp_pkey = self._ffi.gc(evp_ppkey[0], self._lib.EVP_PKEY_free)
1831-
return evp_pkey
1832-
18331813
def x25519_generate_key(self) -> x25519.X25519PrivateKey:
18341814
return rust_openssl.x25519.generate_key()
18351815

@@ -1882,35 +1862,13 @@ def ed448_supported(self) -> bool:
18821862
)
18831863

18841864
def ed448_load_public_bytes(self, data: bytes) -> ed448.Ed448PublicKey:
1885-
utils._check_bytes("data", data)
1886-
if len(data) != _ED448_KEY_SIZE:
1887-
raise ValueError("An Ed448 public key is 57 bytes long")
1888-
1889-
evp_pkey = self._lib.EVP_PKEY_new_raw_public_key(
1890-
self._lib.NID_ED448, self._ffi.NULL, data, len(data)
1891-
)
1892-
self.openssl_assert(evp_pkey != self._ffi.NULL)
1893-
evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free)
1894-
1895-
return _Ed448PublicKey(self, evp_pkey)
1865+
return rust_openssl.ed448.from_public_bytes(data)
18961866

18971867
def ed448_load_private_bytes(self, data: bytes) -> ed448.Ed448PrivateKey:
1898-
utils._check_byteslike("data", data)
1899-
if len(data) != _ED448_KEY_SIZE:
1900-
raise ValueError("An Ed448 private key is 57 bytes long")
1901-
1902-
data_ptr = self._ffi.from_buffer(data)
1903-
evp_pkey = self._lib.EVP_PKEY_new_raw_private_key(
1904-
self._lib.NID_ED448, self._ffi.NULL, data_ptr, len(data)
1905-
)
1906-
self.openssl_assert(evp_pkey != self._ffi.NULL)
1907-
evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free)
1908-
1909-
return _Ed448PrivateKey(self, evp_pkey)
1868+
return rust_openssl.ed448.from_private_bytes(data)
19101869

19111870
def ed448_generate_key(self) -> ed448.Ed448PrivateKey:
1912-
evp_pkey = self._evp_pkey_keygen_gc(self._lib.NID_ED448)
1913-
return _Ed448PrivateKey(self, evp_pkey)
1871+
return rust_openssl.ed448.generate_key()
19141872

19151873
def derive_scrypt(
19161874
self,

src/cryptography/hazmat/backends/openssl/ed448.py

Lines changed: 0 additions & 164 deletions
This file was deleted.

src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44

55
import typing
66

7-
from cryptography.hazmat.bindings._rust.openssl import ed25519, x448, x25519
7+
from cryptography.hazmat.bindings._rust.openssl import (
8+
ed448,
9+
ed25519,
10+
x448,
11+
x25519,
12+
)
813

914
__all__ = [
1015
"openssl_version",
1116
"raise_openssl_error",
17+
"ed448",
1218
"ed25519",
1319
"x448",
1420
"x25519",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# This file is dual licensed under the terms of the Apache License, Version
2+
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3+
# for complete details.
4+
5+
from cryptography.hazmat.primitives.asymmetric import ed448
6+
7+
class Ed448PrivateKey: ...
8+
class Ed448PublicKey: ...
9+
10+
def generate_key() -> ed448.Ed448PrivateKey: ...
11+
def private_key_from_ptr(ptr: int) -> ed448.Ed448PrivateKey: ...
12+
def public_key_from_ptr(ptr: int) -> ed448.Ed448PublicKey: ...
13+
def from_private_bytes(data: bytes) -> ed448.Ed448PrivateKey: ...
14+
def from_public_bytes(data: bytes) -> ed448.Ed448PublicKey: ...

src/cryptography/hazmat/primitives/asymmetric/ed448.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import abc
88

99
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
10+
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
1011
from cryptography.hazmat.primitives import _serialization
1112

1213

@@ -33,14 +34,12 @@ def public_bytes(
3334
The serialized bytes of the public key.
3435
"""
3536

37+
@abc.abstractmethod
3638
def public_bytes_raw(self) -> bytes:
3739
"""
3840
The raw bytes of the public key.
3941
Equivalent to public_bytes(Raw, Raw).
4042
"""
41-
return self.public_bytes(
42-
_serialization.Encoding.Raw, _serialization.PublicFormat.Raw
43-
)
4443

4544
@abc.abstractmethod
4645
def verify(self, signature: bytes, data: bytes) -> None:
@@ -55,6 +54,10 @@ def __eq__(self, other: object) -> bool:
5554
"""
5655

5756

57+
if hasattr(rust_openssl, "ed448"):
58+
Ed448PublicKey.register(rust_openssl.ed448.Ed448PublicKey)
59+
60+
5861
class Ed448PrivateKey(metaclass=abc.ABCMeta):
5962
@classmethod
6063
def generate(cls) -> Ed448PrivateKey:
@@ -102,13 +105,13 @@ def private_bytes(
102105
The serialized bytes of the private key.
103106
"""
104107

108+
@abc.abstractmethod
105109
def private_bytes_raw(self) -> bytes:
106110
"""
107111
The raw bytes of the private key.
108112
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
109113
"""
110-
return self.private_bytes(
111-
_serialization.Encoding.Raw,
112-
_serialization.PrivateFormat.Raw,
113-
_serialization.NoEncryption(),
114-
)
114+
115+
116+
if hasattr(rust_openssl, "x448"):
117+
Ed448PrivateKey.register(rust_openssl.ed448.Ed448PrivateKey)

0 commit comments

Comments
 (0)