rsa.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  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.exceptions import (
  6. InvalidSignature,
  7. UnsupportedAlgorithm,
  8. _Reasons,
  9. )
  10. from cryptography.hazmat.backends.openssl.utils import (
  11. _calculate_digest_and_algorithm,
  12. )
  13. from cryptography.hazmat.primitives import hashes, serialization
  14. from cryptography.hazmat.primitives.asymmetric import (
  15. utils as asym_utils,
  16. )
  17. from cryptography.hazmat.primitives.asymmetric.padding import (
  18. AsymmetricPadding,
  19. MGF1,
  20. OAEP,
  21. PKCS1v15,
  22. PSS,
  23. _Auto,
  24. _DigestLength,
  25. _MaxLength,
  26. calculate_max_pss_salt_length,
  27. )
  28. from cryptography.hazmat.primitives.asymmetric.rsa import (
  29. RSAPrivateKey,
  30. RSAPrivateNumbers,
  31. RSAPublicKey,
  32. RSAPublicNumbers,
  33. )
  34. if typing.TYPE_CHECKING:
  35. from cryptography.hazmat.backends.openssl.backend import Backend
  36. def _get_rsa_pss_salt_length(
  37. backend: "Backend",
  38. pss: PSS,
  39. key: typing.Union[RSAPrivateKey, RSAPublicKey],
  40. hash_algorithm: hashes.HashAlgorithm,
  41. ) -> int:
  42. salt = pss._salt_length
  43. if isinstance(salt, _MaxLength):
  44. return calculate_max_pss_salt_length(key, hash_algorithm)
  45. elif isinstance(salt, _DigestLength):
  46. return hash_algorithm.digest_size
  47. elif isinstance(salt, _Auto):
  48. if isinstance(key, RSAPrivateKey):
  49. raise ValueError(
  50. "PSS salt length can only be set to AUTO when verifying"
  51. )
  52. return backend._lib.RSA_PSS_SALTLEN_AUTO
  53. else:
  54. return salt
  55. def _enc_dec_rsa(
  56. backend: "Backend",
  57. key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"],
  58. data: bytes,
  59. padding: AsymmetricPadding,
  60. ) -> bytes:
  61. if not isinstance(padding, AsymmetricPadding):
  62. raise TypeError("Padding must be an instance of AsymmetricPadding.")
  63. if isinstance(padding, PKCS1v15):
  64. padding_enum = backend._lib.RSA_PKCS1_PADDING
  65. elif isinstance(padding, OAEP):
  66. padding_enum = backend._lib.RSA_PKCS1_OAEP_PADDING
  67. if not isinstance(padding._mgf, MGF1):
  68. raise UnsupportedAlgorithm(
  69. "Only MGF1 is supported by this backend.",
  70. _Reasons.UNSUPPORTED_MGF,
  71. )
  72. if not backend.rsa_padding_supported(padding):
  73. raise UnsupportedAlgorithm(
  74. "This combination of padding and hash algorithm is not "
  75. "supported by this backend.",
  76. _Reasons.UNSUPPORTED_PADDING,
  77. )
  78. else:
  79. raise UnsupportedAlgorithm(
  80. "{} is not supported by this backend.".format(padding.name),
  81. _Reasons.UNSUPPORTED_PADDING,
  82. )
  83. return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding)
  84. def _enc_dec_rsa_pkey_ctx(
  85. backend: "Backend",
  86. key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"],
  87. data: bytes,
  88. padding_enum: int,
  89. padding: AsymmetricPadding,
  90. ) -> bytes:
  91. init: typing.Callable[[typing.Any], int]
  92. crypt: typing.Callable[[typing.Any, typing.Any, int, bytes, int], int]
  93. if isinstance(key, _RSAPublicKey):
  94. init = backend._lib.EVP_PKEY_encrypt_init
  95. crypt = backend._lib.EVP_PKEY_encrypt
  96. else:
  97. init = backend._lib.EVP_PKEY_decrypt_init
  98. crypt = backend._lib.EVP_PKEY_decrypt
  99. pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL)
  100. backend.openssl_assert(pkey_ctx != backend._ffi.NULL)
  101. pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free)
  102. res = init(pkey_ctx)
  103. backend.openssl_assert(res == 1)
  104. res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum)
  105. backend.openssl_assert(res > 0)
  106. buf_size = backend._lib.EVP_PKEY_size(key._evp_pkey)
  107. backend.openssl_assert(buf_size > 0)
  108. if isinstance(padding, OAEP):
  109. mgf1_md = backend._evp_md_non_null_from_algorithm(
  110. padding._mgf._algorithm
  111. )
  112. res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md)
  113. backend.openssl_assert(res > 0)
  114. oaep_md = backend._evp_md_non_null_from_algorithm(padding._algorithm)
  115. res = backend._lib.EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, oaep_md)
  116. backend.openssl_assert(res > 0)
  117. if (
  118. isinstance(padding, OAEP)
  119. and padding._label is not None
  120. and len(padding._label) > 0
  121. ):
  122. # set0_rsa_oaep_label takes ownership of the char * so we need to
  123. # copy it into some new memory
  124. labelptr = backend._lib.OPENSSL_malloc(len(padding._label))
  125. backend.openssl_assert(labelptr != backend._ffi.NULL)
  126. backend._ffi.memmove(labelptr, padding._label, len(padding._label))
  127. res = backend._lib.EVP_PKEY_CTX_set0_rsa_oaep_label(
  128. pkey_ctx, labelptr, len(padding._label)
  129. )
  130. backend.openssl_assert(res == 1)
  131. outlen = backend._ffi.new("size_t *", buf_size)
  132. buf = backend._ffi.new("unsigned char[]", buf_size)
  133. # Everything from this line onwards is written with the goal of being as
  134. # constant-time as is practical given the constraints of Python and our
  135. # API. See Bleichenbacher's '98 attack on RSA, and its many many variants.
  136. # As such, you should not attempt to change this (particularly to "clean it
  137. # up") without understanding why it was written this way (see
  138. # Chesterton's Fence), and without measuring to verify you have not
  139. # introduced observable time differences.
  140. res = crypt(pkey_ctx, buf, outlen, data, len(data))
  141. resbuf = backend._ffi.buffer(buf)[: outlen[0]]
  142. backend._lib.ERR_clear_error()
  143. if res <= 0:
  144. raise ValueError("Encryption/decryption failed.")
  145. return resbuf
  146. def _rsa_sig_determine_padding(
  147. backend: "Backend",
  148. key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"],
  149. padding: AsymmetricPadding,
  150. algorithm: typing.Optional[hashes.HashAlgorithm],
  151. ) -> int:
  152. if not isinstance(padding, AsymmetricPadding):
  153. raise TypeError("Expected provider of AsymmetricPadding.")
  154. pkey_size = backend._lib.EVP_PKEY_size(key._evp_pkey)
  155. backend.openssl_assert(pkey_size > 0)
  156. if isinstance(padding, PKCS1v15):
  157. # Hash algorithm is ignored for PKCS1v15-padding, may be None.
  158. padding_enum = backend._lib.RSA_PKCS1_PADDING
  159. elif isinstance(padding, PSS):
  160. if not isinstance(padding._mgf, MGF1):
  161. raise UnsupportedAlgorithm(
  162. "Only MGF1 is supported by this backend.",
  163. _Reasons.UNSUPPORTED_MGF,
  164. )
  165. # PSS padding requires a hash algorithm
  166. if not isinstance(algorithm, hashes.HashAlgorithm):
  167. raise TypeError("Expected instance of hashes.HashAlgorithm.")
  168. # Size of key in bytes - 2 is the maximum
  169. # PSS signature length (salt length is checked later)
  170. if pkey_size - algorithm.digest_size - 2 < 0:
  171. raise ValueError(
  172. "Digest too large for key size. Use a larger "
  173. "key or different digest."
  174. )
  175. padding_enum = backend._lib.RSA_PKCS1_PSS_PADDING
  176. else:
  177. raise UnsupportedAlgorithm(
  178. "{} is not supported by this backend.".format(padding.name),
  179. _Reasons.UNSUPPORTED_PADDING,
  180. )
  181. return padding_enum
  182. # Hash algorithm can be absent (None) to initialize the context without setting
  183. # any message digest algorithm. This is currently only valid for the PKCS1v15
  184. # padding type, where it means that the signature data is encoded/decoded
  185. # as provided, without being wrapped in a DigestInfo structure.
  186. def _rsa_sig_setup(
  187. backend: "Backend",
  188. padding: AsymmetricPadding,
  189. algorithm: typing.Optional[hashes.HashAlgorithm],
  190. key: typing.Union["_RSAPublicKey", "_RSAPrivateKey"],
  191. init_func: typing.Callable[[typing.Any], int],
  192. ):
  193. padding_enum = _rsa_sig_determine_padding(backend, key, padding, algorithm)
  194. pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL)
  195. backend.openssl_assert(pkey_ctx != backend._ffi.NULL)
  196. pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free)
  197. res = init_func(pkey_ctx)
  198. if res != 1:
  199. errors = backend._consume_errors()
  200. raise ValueError("Unable to sign/verify with this key", errors)
  201. if algorithm is not None:
  202. evp_md = backend._evp_md_non_null_from_algorithm(algorithm)
  203. res = backend._lib.EVP_PKEY_CTX_set_signature_md(pkey_ctx, evp_md)
  204. if res <= 0:
  205. backend._consume_errors()
  206. raise UnsupportedAlgorithm(
  207. "{} is not supported by this backend for RSA signing.".format(
  208. algorithm.name
  209. ),
  210. _Reasons.UNSUPPORTED_HASH,
  211. )
  212. res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum)
  213. if res <= 0:
  214. backend._consume_errors()
  215. raise UnsupportedAlgorithm(
  216. "{} is not supported for the RSA signature operation.".format(
  217. padding.name
  218. ),
  219. _Reasons.UNSUPPORTED_PADDING,
  220. )
  221. if isinstance(padding, PSS):
  222. assert isinstance(algorithm, hashes.HashAlgorithm)
  223. res = backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen(
  224. pkey_ctx,
  225. _get_rsa_pss_salt_length(backend, padding, key, algorithm),
  226. )
  227. backend.openssl_assert(res > 0)
  228. mgf1_md = backend._evp_md_non_null_from_algorithm(
  229. padding._mgf._algorithm
  230. )
  231. res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md)
  232. backend.openssl_assert(res > 0)
  233. return pkey_ctx
  234. def _rsa_sig_sign(
  235. backend: "Backend",
  236. padding: AsymmetricPadding,
  237. algorithm: hashes.HashAlgorithm,
  238. private_key: "_RSAPrivateKey",
  239. data: bytes,
  240. ) -> bytes:
  241. pkey_ctx = _rsa_sig_setup(
  242. backend,
  243. padding,
  244. algorithm,
  245. private_key,
  246. backend._lib.EVP_PKEY_sign_init,
  247. )
  248. buflen = backend._ffi.new("size_t *")
  249. res = backend._lib.EVP_PKEY_sign(
  250. pkey_ctx, backend._ffi.NULL, buflen, data, len(data)
  251. )
  252. backend.openssl_assert(res == 1)
  253. buf = backend._ffi.new("unsigned char[]", buflen[0])
  254. res = backend._lib.EVP_PKEY_sign(pkey_ctx, buf, buflen, data, len(data))
  255. if res != 1:
  256. errors = backend._consume_errors_with_text()
  257. raise ValueError(
  258. "Digest or salt length too long for key size. Use a larger key "
  259. "or shorter salt length if you are specifying a PSS salt",
  260. errors,
  261. )
  262. return backend._ffi.buffer(buf)[:]
  263. def _rsa_sig_verify(
  264. backend: "Backend",
  265. padding: AsymmetricPadding,
  266. algorithm: hashes.HashAlgorithm,
  267. public_key: "_RSAPublicKey",
  268. signature: bytes,
  269. data: bytes,
  270. ) -> None:
  271. pkey_ctx = _rsa_sig_setup(
  272. backend,
  273. padding,
  274. algorithm,
  275. public_key,
  276. backend._lib.EVP_PKEY_verify_init,
  277. )
  278. res = backend._lib.EVP_PKEY_verify(
  279. pkey_ctx, signature, len(signature), data, len(data)
  280. )
  281. # The previous call can return negative numbers in the event of an
  282. # error. This is not a signature failure but we need to fail if it
  283. # occurs.
  284. backend.openssl_assert(res >= 0)
  285. if res == 0:
  286. backend._consume_errors()
  287. raise InvalidSignature
  288. def _rsa_sig_recover(
  289. backend: "Backend",
  290. padding: AsymmetricPadding,
  291. algorithm: typing.Optional[hashes.HashAlgorithm],
  292. public_key: "_RSAPublicKey",
  293. signature: bytes,
  294. ) -> bytes:
  295. pkey_ctx = _rsa_sig_setup(
  296. backend,
  297. padding,
  298. algorithm,
  299. public_key,
  300. backend._lib.EVP_PKEY_verify_recover_init,
  301. )
  302. # Attempt to keep the rest of the code in this function as constant/time
  303. # as possible. See the comment in _enc_dec_rsa_pkey_ctx. Note that the
  304. # buflen parameter is used even though its value may be undefined in the
  305. # error case. Due to the tolerant nature of Python slicing this does not
  306. # trigger any exceptions.
  307. maxlen = backend._lib.EVP_PKEY_size(public_key._evp_pkey)
  308. backend.openssl_assert(maxlen > 0)
  309. buf = backend._ffi.new("unsigned char[]", maxlen)
  310. buflen = backend._ffi.new("size_t *", maxlen)
  311. res = backend._lib.EVP_PKEY_verify_recover(
  312. pkey_ctx, buf, buflen, signature, len(signature)
  313. )
  314. resbuf = backend._ffi.buffer(buf)[: buflen[0]]
  315. backend._lib.ERR_clear_error()
  316. # Assume that all parameter errors are handled during the setup phase and
  317. # any error here is due to invalid signature.
  318. if res != 1:
  319. raise InvalidSignature
  320. return resbuf
  321. class _RSAPrivateKey(RSAPrivateKey):
  322. _evp_pkey: object
  323. _rsa_cdata: object
  324. _key_size: int
  325. def __init__(
  326. self, backend: "Backend", rsa_cdata, evp_pkey, _skip_check_key: bool
  327. ):
  328. res: int
  329. # RSA_check_key is slower in OpenSSL 3.0.0 due to improved
  330. # primality checking. In normal use this is unlikely to be a problem
  331. # since users don't load new keys constantly, but for TESTING we've
  332. # added an init arg that allows skipping the checks. You should not
  333. # use this in production code unless you understand the consequences.
  334. if not _skip_check_key:
  335. res = backend._lib.RSA_check_key(rsa_cdata)
  336. if res != 1:
  337. errors = backend._consume_errors_with_text()
  338. raise ValueError("Invalid private key", errors)
  339. # 2 is prime and passes an RSA key check, so we also check
  340. # if p and q are odd just to be safe.
  341. p = backend._ffi.new("BIGNUM **")
  342. q = backend._ffi.new("BIGNUM **")
  343. backend._lib.RSA_get0_factors(rsa_cdata, p, q)
  344. backend.openssl_assert(p[0] != backend._ffi.NULL)
  345. backend.openssl_assert(q[0] != backend._ffi.NULL)
  346. p_odd = backend._lib.BN_is_odd(p[0])
  347. q_odd = backend._lib.BN_is_odd(q[0])
  348. if p_odd != 1 or q_odd != 1:
  349. errors = backend._consume_errors_with_text()
  350. raise ValueError("Invalid private key", errors)
  351. # Blinding is on by default in many versions of OpenSSL, but let's
  352. # just be conservative here.
  353. res = backend._lib.RSA_blinding_on(rsa_cdata, backend._ffi.NULL)
  354. backend.openssl_assert(res == 1)
  355. self._backend = backend
  356. self._rsa_cdata = rsa_cdata
  357. self._evp_pkey = evp_pkey
  358. n = self._backend._ffi.new("BIGNUM **")
  359. self._backend._lib.RSA_get0_key(
  360. self._rsa_cdata,
  361. n,
  362. self._backend._ffi.NULL,
  363. self._backend._ffi.NULL,
  364. )
  365. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  366. self._key_size = self._backend._lib.BN_num_bits(n[0])
  367. @property
  368. def key_size(self) -> int:
  369. return self._key_size
  370. def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes:
  371. key_size_bytes = (self.key_size + 7) // 8
  372. if key_size_bytes != len(ciphertext):
  373. raise ValueError("Ciphertext length must be equal to key size.")
  374. return _enc_dec_rsa(self._backend, self, ciphertext, padding)
  375. def public_key(self) -> RSAPublicKey:
  376. ctx = self._backend._lib.RSAPublicKey_dup(self._rsa_cdata)
  377. self._backend.openssl_assert(ctx != self._backend._ffi.NULL)
  378. ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free)
  379. evp_pkey = self._backend._rsa_cdata_to_evp_pkey(ctx)
  380. return _RSAPublicKey(self._backend, ctx, evp_pkey)
  381. def private_numbers(self) -> RSAPrivateNumbers:
  382. n = self._backend._ffi.new("BIGNUM **")
  383. e = self._backend._ffi.new("BIGNUM **")
  384. d = self._backend._ffi.new("BIGNUM **")
  385. p = self._backend._ffi.new("BIGNUM **")
  386. q = self._backend._ffi.new("BIGNUM **")
  387. dmp1 = self._backend._ffi.new("BIGNUM **")
  388. dmq1 = self._backend._ffi.new("BIGNUM **")
  389. iqmp = self._backend._ffi.new("BIGNUM **")
  390. self._backend._lib.RSA_get0_key(self._rsa_cdata, n, e, d)
  391. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  392. self._backend.openssl_assert(e[0] != self._backend._ffi.NULL)
  393. self._backend.openssl_assert(d[0] != self._backend._ffi.NULL)
  394. self._backend._lib.RSA_get0_factors(self._rsa_cdata, p, q)
  395. self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
  396. self._backend.openssl_assert(q[0] != self._backend._ffi.NULL)
  397. self._backend._lib.RSA_get0_crt_params(
  398. self._rsa_cdata, dmp1, dmq1, iqmp
  399. )
  400. self._backend.openssl_assert(dmp1[0] != self._backend._ffi.NULL)
  401. self._backend.openssl_assert(dmq1[0] != self._backend._ffi.NULL)
  402. self._backend.openssl_assert(iqmp[0] != self._backend._ffi.NULL)
  403. return RSAPrivateNumbers(
  404. p=self._backend._bn_to_int(p[0]),
  405. q=self._backend._bn_to_int(q[0]),
  406. d=self._backend._bn_to_int(d[0]),
  407. dmp1=self._backend._bn_to_int(dmp1[0]),
  408. dmq1=self._backend._bn_to_int(dmq1[0]),
  409. iqmp=self._backend._bn_to_int(iqmp[0]),
  410. public_numbers=RSAPublicNumbers(
  411. e=self._backend._bn_to_int(e[0]),
  412. n=self._backend._bn_to_int(n[0]),
  413. ),
  414. )
  415. def private_bytes(
  416. self,
  417. encoding: serialization.Encoding,
  418. format: serialization.PrivateFormat,
  419. encryption_algorithm: serialization.KeySerializationEncryption,
  420. ) -> bytes:
  421. return self._backend._private_key_bytes(
  422. encoding,
  423. format,
  424. encryption_algorithm,
  425. self,
  426. self._evp_pkey,
  427. self._rsa_cdata,
  428. )
  429. def sign(
  430. self,
  431. data: bytes,
  432. padding: AsymmetricPadding,
  433. algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
  434. ) -> bytes:
  435. data, algorithm = _calculate_digest_and_algorithm(data, algorithm)
  436. return _rsa_sig_sign(self._backend, padding, algorithm, self, data)
  437. class _RSAPublicKey(RSAPublicKey):
  438. _evp_pkey: object
  439. _rsa_cdata: object
  440. _key_size: int
  441. def __init__(self, backend: "Backend", rsa_cdata, evp_pkey):
  442. self._backend = backend
  443. self._rsa_cdata = rsa_cdata
  444. self._evp_pkey = evp_pkey
  445. n = self._backend._ffi.new("BIGNUM **")
  446. self._backend._lib.RSA_get0_key(
  447. self._rsa_cdata,
  448. n,
  449. self._backend._ffi.NULL,
  450. self._backend._ffi.NULL,
  451. )
  452. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  453. self._key_size = self._backend._lib.BN_num_bits(n[0])
  454. @property
  455. def key_size(self) -> int:
  456. return self._key_size
  457. def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes:
  458. return _enc_dec_rsa(self._backend, self, plaintext, padding)
  459. def public_numbers(self) -> RSAPublicNumbers:
  460. n = self._backend._ffi.new("BIGNUM **")
  461. e = self._backend._ffi.new("BIGNUM **")
  462. self._backend._lib.RSA_get0_key(
  463. self._rsa_cdata, n, e, self._backend._ffi.NULL
  464. )
  465. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  466. self._backend.openssl_assert(e[0] != self._backend._ffi.NULL)
  467. return RSAPublicNumbers(
  468. e=self._backend._bn_to_int(e[0]),
  469. n=self._backend._bn_to_int(n[0]),
  470. )
  471. def public_bytes(
  472. self,
  473. encoding: serialization.Encoding,
  474. format: serialization.PublicFormat,
  475. ) -> bytes:
  476. return self._backend._public_key_bytes(
  477. encoding, format, self, self._evp_pkey, self._rsa_cdata
  478. )
  479. def verify(
  480. self,
  481. signature: bytes,
  482. data: bytes,
  483. padding: AsymmetricPadding,
  484. algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
  485. ) -> None:
  486. data, algorithm = _calculate_digest_and_algorithm(data, algorithm)
  487. _rsa_sig_verify(
  488. self._backend, padding, algorithm, self, signature, data
  489. )
  490. def recover_data_from_signature(
  491. self,
  492. signature: bytes,
  493. padding: AsymmetricPadding,
  494. algorithm: typing.Optional[hashes.HashAlgorithm],
  495. ) -> bytes:
  496. if isinstance(algorithm, asym_utils.Prehashed):
  497. raise TypeError(
  498. "Prehashed is only supported in the sign and verify methods. "
  499. "It cannot be used with recover_data_from_signature."
  500. )
  501. return _rsa_sig_recover(
  502. self._backend, padding, algorithm, self, signature
  503. )