x448.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. import typing
  5. from cryptography.hazmat.backends.openssl.utils import _evp_pkey_derive
  6. from cryptography.hazmat.primitives import serialization
  7. from cryptography.hazmat.primitives.asymmetric.x448 import (
  8. X448PrivateKey,
  9. X448PublicKey,
  10. )
  11. if typing.TYPE_CHECKING:
  12. from cryptography.hazmat.backends.openssl.backend import Backend
  13. _X448_KEY_SIZE = 56
  14. class _X448PublicKey(X448PublicKey):
  15. def __init__(self, backend: "Backend", evp_pkey):
  16. self._backend = backend
  17. self._evp_pkey = evp_pkey
  18. def public_bytes(
  19. self,
  20. encoding: serialization.Encoding,
  21. format: serialization.PublicFormat,
  22. ) -> bytes:
  23. if (
  24. encoding is serialization.Encoding.Raw
  25. or format is serialization.PublicFormat.Raw
  26. ):
  27. if (
  28. encoding is not serialization.Encoding.Raw
  29. or format is not serialization.PublicFormat.Raw
  30. ):
  31. raise ValueError(
  32. "When using Raw both encoding and format must be Raw"
  33. )
  34. return self._raw_public_bytes()
  35. return self._backend._public_key_bytes(
  36. encoding, format, self, self._evp_pkey, None
  37. )
  38. def _raw_public_bytes(self) -> bytes:
  39. buf = self._backend._ffi.new("unsigned char []", _X448_KEY_SIZE)
  40. buflen = self._backend._ffi.new("size_t *", _X448_KEY_SIZE)
  41. res = self._backend._lib.EVP_PKEY_get_raw_public_key(
  42. self._evp_pkey, buf, buflen
  43. )
  44. self._backend.openssl_assert(res == 1)
  45. self._backend.openssl_assert(buflen[0] == _X448_KEY_SIZE)
  46. return self._backend._ffi.buffer(buf, _X448_KEY_SIZE)[:]
  47. class _X448PrivateKey(X448PrivateKey):
  48. def __init__(self, backend: "Backend", evp_pkey):
  49. self._backend = backend
  50. self._evp_pkey = evp_pkey
  51. def public_key(self) -> X448PublicKey:
  52. buf = self._backend._ffi.new("unsigned char []", _X448_KEY_SIZE)
  53. buflen = self._backend._ffi.new("size_t *", _X448_KEY_SIZE)
  54. res = self._backend._lib.EVP_PKEY_get_raw_public_key(
  55. self._evp_pkey, buf, buflen
  56. )
  57. self._backend.openssl_assert(res == 1)
  58. self._backend.openssl_assert(buflen[0] == _X448_KEY_SIZE)
  59. public_bytes = self._backend._ffi.buffer(buf)[:]
  60. return self._backend.x448_load_public_bytes(public_bytes)
  61. def exchange(self, peer_public_key: X448PublicKey) -> bytes:
  62. if not isinstance(peer_public_key, X448PublicKey):
  63. raise TypeError("peer_public_key must be X448PublicKey.")
  64. return _evp_pkey_derive(self._backend, self._evp_pkey, peer_public_key)
  65. def private_bytes(
  66. self,
  67. encoding: serialization.Encoding,
  68. format: serialization.PrivateFormat,
  69. encryption_algorithm: serialization.KeySerializationEncryption,
  70. ) -> bytes:
  71. if (
  72. encoding is serialization.Encoding.Raw
  73. or format is serialization.PublicFormat.Raw
  74. ):
  75. if (
  76. format is not serialization.PrivateFormat.Raw
  77. or encoding is not serialization.Encoding.Raw
  78. or not isinstance(
  79. encryption_algorithm, serialization.NoEncryption
  80. )
  81. ):
  82. raise ValueError(
  83. "When using Raw both encoding and format must be Raw "
  84. "and encryption_algorithm must be NoEncryption()"
  85. )
  86. return self._raw_private_bytes()
  87. return self._backend._private_key_bytes(
  88. encoding, format, encryption_algorithm, self, self._evp_pkey, None
  89. )
  90. def _raw_private_bytes(self) -> bytes:
  91. buf = self._backend._ffi.new("unsigned char []", _X448_KEY_SIZE)
  92. buflen = self._backend._ffi.new("size_t *", _X448_KEY_SIZE)
  93. res = self._backend._lib.EVP_PKEY_get_raw_private_key(
  94. self._evp_pkey, buf, buflen
  95. )
  96. self._backend.openssl_assert(res == 1)
  97. self._backend.openssl_assert(buflen[0] == _X448_KEY_SIZE)
  98. return self._backend._ffi.buffer(buf, _X448_KEY_SIZE)[:]