Skip to main content

aws_lc_rs/rsa/
key.rs

1// Copyright 2015-2016 Brian Smith.
2// SPDX-License-Identifier: ISC
3// Modifications copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4// SPDX-License-Identifier: Apache-2.0 OR ISC
5use super::signature::{RsaEncoding, RsaPadding};
6use super::{encoding, RsaParameters};
7use crate::aws_lc::{
8    EVP_PKEY_CTX_set_rsa_keygen_bits, EVP_PKEY_CTX_set_signature_md, EVP_PKEY_assign_RSA,
9    EVP_PKEY_new, RSA_new, RSA_set0_key, RSA_size, EVP_PKEY, EVP_PKEY_CTX, EVP_PKEY_RSA,
10    EVP_PKEY_RSA_PSS,
11};
12#[cfg(feature = "ring-io")]
13use crate::aws_lc::{RSA_get0_e, RSA_get0_n};
14use crate::encoding::{AsDer, Pkcs8V1Der, PublicKeyX509Der};
15use crate::error::{KeyRejected, Unspecified};
16#[cfg(feature = "ring-io")]
17use crate::io;
18use crate::ptr::{DetachableLcPtr, LcPtr};
19use crate::rsa::PublicEncryptingKey;
20use crate::sealed::Sealed;
21use crate::{hex, rand};
22#[cfg(feature = "fips")]
23use aws_lc::RSA_check_fips;
24use core::fmt::{self, Debug, Formatter};
25use core::ptr::null_mut;
26
27// TODO: Uncomment when MSRV >= 1.64
28// use core::ffi::c_int;
29use std::os::raw::c_int;
30
31use crate::digest::{match_digest_type, Digest};
32use crate::pkcs8::Version;
33use crate::rsa::encoding::{rfc5280, rfc8017};
34use crate::rsa::signature::configure_rsa_pkcs1_pss_padding;
35#[cfg(feature = "ring-io")]
36use untrusted::Input;
37use zeroize::Zeroize;
38
39/// RSA key-size.
40#[allow(clippy::module_name_repetitions)]
41#[non_exhaustive]
42#[derive(Clone, Copy, Debug, PartialEq, Eq)]
43pub enum KeySize {
44    /// 2048-bit key
45    Rsa2048,
46
47    /// 3072-bit key
48    Rsa3072,
49
50    /// 4096-bit key
51    Rsa4096,
52
53    /// 8192-bit key
54    Rsa8192,
55}
56
57#[allow(clippy::len_without_is_empty)]
58impl KeySize {
59    /// Returns the size of the key in bytes.
60    #[inline]
61    #[must_use]
62    pub fn len(self) -> usize {
63        match self {
64            Self::Rsa2048 => 256,
65            Self::Rsa3072 => 384,
66            Self::Rsa4096 => 512,
67            Self::Rsa8192 => 1024,
68        }
69    }
70
71    /// Returns the key size in bits.
72    #[inline]
73    pub(super) fn bits(self) -> i32 {
74        match self {
75            Self::Rsa2048 => 2048,
76            Self::Rsa3072 => 3072,
77            Self::Rsa4096 => 4096,
78            Self::Rsa8192 => 8192,
79        }
80    }
81}
82
83/// An RSA key pair, used for signing.
84#[allow(clippy::module_name_repetitions)]
85pub struct KeyPair {
86    // https://github.com/aws/aws-lc/blob/ebaa07a207fee02bd68fe8d65f6b624afbf29394/include/openssl/evp.h#L295
87    // An |EVP_PKEY| object represents a public or private RSA key. A given object may be
88    // used concurrently on multiple threads by non-mutating functions, provided no
89    // other thread is concurrently calling a mutating function. Unless otherwise
90    // documented, functions which take a |const| pointer are non-mutating and
91    // functions which take a non-|const| pointer are mutating.
92    pub(super) evp_pkey: LcPtr<EVP_PKEY>,
93    pub(super) serialized_public_key: PublicKey,
94}
95
96impl Sealed for KeyPair {}
97unsafe impl Send for KeyPair {}
98unsafe impl Sync for KeyPair {}
99
100impl KeyPair {
101    fn new(evp_pkey: LcPtr<EVP_PKEY>) -> Result<Self, KeyRejected> {
102        KeyPair::validate_private_key(&evp_pkey)?;
103        let serialized_public_key = PublicKey::new(&evp_pkey)?;
104        Ok(KeyPair {
105            evp_pkey,
106            serialized_public_key,
107        })
108    }
109
110    /// Generate a RSA `KeyPair` of the specified key-strength.
111    ///
112    /// Supports the following key sizes:
113    /// * `KeySize::Rsa2048`
114    /// * `KeySize::Rsa3072`
115    /// * `KeySize::Rsa4096`
116    /// * `KeySize::Rsa8192`
117    ///
118    /// # Errors
119    /// * `Unspecified`: Any key generation failure.
120    pub fn generate(size: KeySize) -> Result<Self, Unspecified> {
121        let private_key = generate_rsa_key(size.bits())?;
122        Ok(Self::new(private_key)?)
123    }
124
125    /// Generate a RSA `KeyPair` of the specified key-strength.
126    ///
127    /// ## Deprecated
128    /// This is equivalent to `KeyPair::generate`.
129    ///
130    /// # Errors
131    /// * `Unspecified`: Any key generation failure.
132    #[cfg(feature = "fips")]
133    #[deprecated]
134    pub fn generate_fips(size: KeySize) -> Result<Self, Unspecified> {
135        Self::generate(size)
136    }
137
138    /// Parses an unencrypted PKCS#8 DER encoded RSA private key.
139    ///
140    /// Keys can be generated using [`KeyPair::generate`].
141    ///
142    /// # *ring*-compatibility
143    ///
144    /// *aws-lc-rs* does not impose the same limitations that *ring* does for
145    /// RSA keys. Thus signatures may be generated by keys that are not accepted
146    /// by *ring*. In particular:
147    /// * RSA private keys ranging between 2048-bit keys and 8192-bit keys are supported.
148    /// * The public exponent does not have a required minimum size.
149    ///
150    /// # Errors
151    /// `error::KeyRejected` if bytes do not encode an RSA private key or if the key is otherwise
152    /// not acceptable.
153    pub fn from_pkcs8(pkcs8: &[u8]) -> Result<Self, KeyRejected> {
154        let key = LcPtr::<EVP_PKEY>::parse_rfc5208_private_key(pkcs8, EVP_PKEY_RSA)?;
155        Self::new(key)
156    }
157
158    /// Parses a DER-encoded `RSAPrivateKey` structure (RFC 8017).
159    ///
160    /// # Errors
161    /// `error:KeyRejected` on error.
162    pub fn from_der(input: &[u8]) -> Result<Self, KeyRejected> {
163        let key = encoding::rfc8017::decode_private_key_der(input)?;
164        Self::new(key)
165    }
166
167    /// Returns a boolean indicator if this RSA key is an approved FIPS 140-3 key.
168    #[cfg(feature = "fips")]
169    #[must_use]
170    pub fn is_valid_fips_key(&self) -> bool {
171        is_valid_fips_key(&self.evp_pkey)
172    }
173
174    fn validate_private_key(key: &LcPtr<EVP_PKEY>) -> Result<(), KeyRejected> {
175        validate_rsa_key(key)
176    }
177
178    /// Sign `msg`. `msg` is digested using the digest algorithm from
179    /// `padding_alg` and the digest is then padded using the padding algorithm
180    /// from `padding_alg`. The signature is written into `signature`;
181    /// `signature`'s length must be exactly the length returned by
182    /// `public_modulus_len()`.
183    ///
184    /// This function does *not* take a precomputed digest; instead, `sign`
185    /// calculates the digest itself. See `sign_digest`.
186    ///
187    /// # *ring* Compatibility
188    /// Our implementation ignores the `SecureRandom` parameter.
189    // # FIPS
190    // The following conditions must be met:
191    // * RSA Key Sizes: 2048, 3072, 4096
192    // * Digest Algorithms: SHA256, SHA384, SHA512
193    //
194    /// # Errors
195    /// `error::Unspecified` on error.
196    /// With "fips" feature enabled, errors if digest length is greater than `u32::MAX`.
197    pub fn sign(
198        &self,
199        padding_alg: &'static dyn RsaEncoding,
200        _rng: &dyn rand::SecureRandom,
201        msg: &[u8],
202        signature: &mut [u8],
203    ) -> Result<(), Unspecified> {
204        let encoding = padding_alg.encoding();
205        let padding_fn = if let RsaPadding::RSA_PKCS1_PSS_PADDING = encoding.padding() {
206            Some(configure_rsa_pkcs1_pss_padding)
207        } else {
208            None
209        };
210
211        let sig_bytes = self
212            .evp_pkey
213            .sign(msg, Some(encoding.digest_algorithm()), padding_fn)?;
214
215        signature.copy_from_slice(&sig_bytes);
216        Ok(())
217    }
218
219    /// The `digest` is padded using the padding algorithm
220    /// from `padding_alg`. The signature is written into `signature`;
221    /// `signature`'s length must be exactly the length returned by
222    /// `public_modulus_len()`.
223    ///
224    /// # *ring* Compatibility
225    /// Our implementation ignores the `SecureRandom` parameter.
226    //
227    // # FIPS
228    // Not allowed
229    //
230    /// # Errors
231    /// `error::Unspecified` on error.
232    /// With "fips" feature enabled, errors if digest length is greater than `u32::MAX`.
233    pub fn sign_digest(
234        &self,
235        padding_alg: &'static dyn RsaEncoding,
236        digest: &Digest,
237        signature: &mut [u8],
238    ) -> Result<(), Unspecified> {
239        let encoding = padding_alg.encoding();
240        if encoding.digest_algorithm() != digest.algorithm() {
241            return Err(Unspecified);
242        }
243
244        let padding_fn = Some({
245            |pctx: *mut EVP_PKEY_CTX| {
246                let evp_md = match_digest_type(&digest.algorithm().id);
247                if 1 != unsafe { EVP_PKEY_CTX_set_signature_md(pctx, evp_md.as_const_ptr()) } {
248                    return Err(());
249                }
250                if let RsaPadding::RSA_PKCS1_PSS_PADDING = encoding.padding() {
251                    configure_rsa_pkcs1_pss_padding(pctx)
252                } else {
253                    Ok(())
254                }
255            }
256        });
257
258        let sig_bytes = self.evp_pkey.sign_digest(digest, padding_fn)?;
259
260        signature.copy_from_slice(&sig_bytes);
261        Ok(())
262    }
263
264    /// Returns the length in bytes of the key pair's public modulus.
265    ///
266    /// A signature has the same length as the public modulus.
267    #[must_use]
268    pub fn public_modulus_len(&self) -> usize {
269        // This was already validated to be an RSA key so this can't fail
270        match self.evp_pkey.as_const().get_rsa() {
271            Ok(rsa) => {
272                // https://github.com/awslabs/aws-lc/blob/main/include/openssl/rsa.h#L99
273                unsafe { RSA_size(rsa.as_const_ptr()) as usize }
274            }
275            Err(_) => unreachable!(),
276        }
277    }
278}
279
280impl Debug for KeyPair {
281    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
282        f.write_str(&format!(
283            "RsaKeyPair {{ public_key: {:?} }}",
284            self.serialized_public_key
285        ))
286    }
287}
288
289impl crate::signature::KeyPair for KeyPair {
290    type PublicKey = PublicKey;
291
292    fn public_key(&self) -> &Self::PublicKey {
293        &self.serialized_public_key
294    }
295}
296
297impl AsDer<Pkcs8V1Der<'static>> for KeyPair {
298    fn as_der(&self) -> Result<Pkcs8V1Der<'static>, Unspecified> {
299        Ok(Pkcs8V1Der::new(
300            self.evp_pkey
301                .as_const()
302                .marshal_rfc5208_private_key(Version::V1)?,
303        ))
304    }
305}
306
307/// A serialized RSA public key.
308#[derive(Clone)]
309#[allow(clippy::module_name_repetitions)]
310pub struct PublicKey {
311    key: Box<[u8]>,
312    #[cfg(feature = "ring-io")]
313    modulus: Box<[u8]>,
314    #[cfg(feature = "ring-io")]
315    exponent: Box<[u8]>,
316}
317
318impl Drop for PublicKey {
319    fn drop(&mut self) {
320        self.key.zeroize();
321        #[cfg(feature = "ring-io")]
322        self.modulus.zeroize();
323        #[cfg(feature = "ring-io")]
324        self.exponent.zeroize();
325    }
326}
327
328impl PublicKey {
329    pub(super) fn new(evp_pkey: &LcPtr<EVP_PKEY>) -> Result<Self, KeyRejected> {
330        let key = encoding::rfc8017::encode_public_key_der(evp_pkey)?;
331        #[cfg(feature = "ring-io")]
332        {
333            let evp_pkey = evp_pkey.as_const();
334            let pubkey = evp_pkey.get_rsa()?;
335            let modulus = pubkey
336                .project_const_lifetime(unsafe { |pubkey| RSA_get0_n(pubkey.as_const_ptr()) })?;
337            let modulus = modulus.to_be_bytes().into_boxed_slice();
338            let exponent = pubkey
339                .project_const_lifetime(unsafe { |pubkey| RSA_get0_e(pubkey.as_const_ptr()) })?;
340            let exponent = exponent.to_be_bytes().into_boxed_slice();
341            Ok(PublicKey {
342                key,
343                modulus,
344                exponent,
345            })
346        }
347
348        #[cfg(not(feature = "ring-io"))]
349        Ok(PublicKey { key })
350    }
351
352    /// Parses an RSA public key from either RFC8017 or RFC5280
353    /// # Errors
354    /// `KeyRejected` if the encoding is not for a valid RSA key.
355    pub fn from_der(input: &[u8]) -> Result<Self, KeyRejected> {
356        // These both invoke `RSA_check_key`:
357        // https://github.com/aws/aws-lc/blob/4368aaa6975ba41bd76d3bb12fac54c4680247fb/crypto/rsa_extra/rsa_asn1.c#L105-L109
358        PublicKey::new(
359            &rfc8017::decode_public_key_der(input).or(rfc5280::decode_public_key_der(input))?,
360        )
361    }
362}
363
364pub(crate) fn parse_rsa_public_key(input: &[u8]) -> Result<LcPtr<EVP_PKEY>, KeyRejected> {
365    rfc8017::decode_public_key_der(input).or(rfc5280::decode_public_key_der(input))
366}
367
368impl Debug for PublicKey {
369    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
370        f.write_str(&format!(
371            "RsaPublicKey(\"{}\")",
372            hex::encode(self.key.as_ref())
373        ))
374    }
375}
376
377impl AsRef<[u8]> for PublicKey {
378    /// DER encode a RSA public key to (RFC 8017) `RSAPublicKey` structure.
379    fn as_ref(&self) -> &[u8] {
380        self.key.as_ref()
381    }
382}
383
384impl AsDer<PublicKeyX509Der<'static>> for PublicKey {
385    fn as_der(&self) -> Result<PublicKeyX509Der<'static>, Unspecified> {
386        // TODO: refactor
387        let evp_pkey = rfc8017::decode_public_key_der(self.as_ref())?;
388        rfc5280::encode_public_key_der(&evp_pkey)
389    }
390}
391
392#[cfg(feature = "ring-io")]
393impl PublicKey {
394    /// The public modulus (n).
395    #[must_use]
396    pub fn modulus(&self) -> io::Positive<'_> {
397        io::Positive::new_non_empty_without_leading_zeros(Input::from(self.modulus.as_ref()))
398    }
399
400    /// The public exponent (e).
401    #[must_use]
402    pub fn exponent(&self) -> io::Positive<'_> {
403        io::Positive::new_non_empty_without_leading_zeros(Input::from(self.exponent.as_ref()))
404    }
405
406    /// Returns the length in bytes of the public modulus.
407    #[must_use]
408    pub fn modulus_len(&self) -> usize {
409        self.modulus.len()
410    }
411}
412
413/// Low-level API for RSA public keys.
414///
415/// When the public key is in DER-encoded PKCS#1 ASN.1 format, it is
416/// recommended to use `aws_lc_rs::signature::verify()` with
417/// `aws_lc_rs::signature::RSA_PKCS1_*`, because `aws_lc_rs::signature::verify()`
418/// will handle the parsing in that case. Otherwise, this function can be used
419/// to pass in the raw bytes for the public key components as
420/// `untrusted::Input` arguments.
421#[allow(clippy::module_name_repetitions)]
422#[derive(Clone)]
423pub struct PublicKeyComponents<B>
424where
425    B: AsRef<[u8]> + Debug,
426{
427    /// The public modulus, encoded in big-endian bytes without leading zeros.
428    pub n: B,
429    /// The public exponent, encoded in big-endian bytes without leading zeros.
430    pub e: B,
431}
432
433impl<B: AsRef<[u8]> + Debug> Debug for PublicKeyComponents<B> {
434    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
435        f.debug_struct("RsaPublicKeyComponents")
436            .field("n", &self.n)
437            .field("e", &self.e)
438            .finish()
439    }
440}
441
442impl<B: Copy + AsRef<[u8]> + Debug> Copy for PublicKeyComponents<B> {}
443
444impl<B> PublicKeyComponents<B>
445where
446    B: AsRef<[u8]> + Debug,
447{
448    #[inline]
449    fn build_rsa(&self) -> Result<LcPtr<EVP_PKEY>, ()> {
450        let n_bytes = self.n.as_ref();
451        if n_bytes.is_empty() || n_bytes[0] == 0u8 {
452            return Err(());
453        }
454        let mut n_bn = DetachableLcPtr::try_from(n_bytes)?;
455
456        let e_bytes = self.e.as_ref();
457        if e_bytes.is_empty() || e_bytes[0] == 0u8 {
458            return Err(());
459        }
460        let mut e_bn = DetachableLcPtr::try_from(e_bytes)?;
461
462        let mut rsa = DetachableLcPtr::new(unsafe { RSA_new() })?;
463        if 1 != unsafe {
464            RSA_set0_key(
465                rsa.as_mut_ptr(),
466                n_bn.as_mut_ptr(),
467                e_bn.as_mut_ptr(),
468                null_mut(),
469            )
470        } {
471            return Err(());
472        }
473        n_bn.detach();
474        e_bn.detach();
475
476        let mut pkey = LcPtr::new(unsafe { EVP_PKEY_new() })?;
477        if 1 != unsafe { EVP_PKEY_assign_RSA(pkey.as_mut_ptr(), rsa.as_mut_ptr()) } {
478            return Err(());
479        }
480        rsa.detach();
481
482        Ok(pkey)
483    }
484
485    /// Verifies that `signature` is a valid signature of `message` using `self`
486    /// as the public key. `params` determine what algorithm parameters
487    /// (padding, digest algorithm, key length range, etc.) are used in the
488    /// verification.
489    ///
490    /// # Errors
491    /// `error::Unspecified` if `message` was not verified.
492    pub fn verify(
493        &self,
494        params: &RsaParameters,
495        message: &[u8],
496        signature: &[u8],
497    ) -> Result<(), Unspecified> {
498        let rsa = self.build_rsa()?;
499        super::signature::verify_rsa_signature(
500            params.digest_algorithm(),
501            params.padding(),
502            &rsa,
503            message,
504            signature,
505            params.bit_size_range(),
506        )
507    }
508
509    /// Parses these components into a [`crate::signature::ParsedPublicKey`],
510    /// which can then be used to verify multiple signatures while amortizing
511    /// the cost of key parsing.
512    ///
513    /// `params` specifies the RSA verification algorithm, such as
514    /// [`crate::signature::RSA_PKCS1_2048_8192_SHA256`] or
515    /// [`crate::signature::RSA_PSS_2048_8192_SHA256`].
516    ///
517    /// Note that the algorithm's accepted key-size range is *not* enforced at
518    /// this point; that check is deferred to
519    /// [`crate::signature::ParsedPublicKey::verify_sig`], matching the
520    /// behavior of [`crate::signature::ParsedPublicKey::new`].
521    ///
522    /// # Errors
523    /// `KeyRejected` if `self` does not form a valid RSA public key.
524    ///
525    /// # Examples
526    ///
527    /// ```no_run
528    /// use aws_lc_rs::signature::{self, RsaPublicKeyComponents};
529    ///
530    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
531    /// # fn modulus_bytes() -> &'static [u8] { &[] }
532    /// # fn exponent_bytes() -> &'static [u8] { &[] }
533    /// # fn signature_bytes() -> &'static [u8] { &[] }
534    /// // Public key components (big-endian, no leading zeros) received
535    /// // out-of-band from a peer.
536    /// let components = RsaPublicKeyComponents {
537    ///     n: modulus_bytes(),
538    ///     e: exponent_bytes(),
539    /// };
540    /// let parsed =
541    ///     components.to_parsed_public_key(&signature::RSA_PKCS1_2048_8192_SHA256)?;
542    /// parsed.verify_sig(b"hello, world", signature_bytes())?;
543    /// # Ok(()) }
544    /// ```
545    pub fn to_parsed_public_key(
546        &self,
547        params: &'static RsaParameters,
548    ) -> Result<crate::signature::ParsedPublicKey, KeyRejected> {
549        let pkey = self
550            .build_rsa()
551            .map_err(|()| KeyRejected::inconsistent_components())?;
552        Ok(crate::signature::ParsedPublicKey::from_rsa_evp_pkey(
553            params, pkey,
554        )?)
555    }
556}
557
558#[cfg(feature = "ring-io")]
559impl From<&PublicKey> for PublicKeyComponents<Vec<u8>> {
560    fn from(public_key: &PublicKey) -> Self {
561        PublicKeyComponents {
562            n: public_key.modulus.to_vec(),
563            e: public_key.exponent.to_vec(),
564        }
565    }
566}
567
568impl<B> TryInto<PublicEncryptingKey> for PublicKeyComponents<B>
569where
570    B: AsRef<[u8]> + Debug,
571{
572    type Error = Unspecified;
573
574    /// Try to build a `PublicEncryptingKey` from the public key components.
575    ///
576    /// # Errors
577    /// `error::Unspecified` if the key failed to verify.
578    fn try_into(self) -> Result<PublicEncryptingKey, Self::Error> {
579        let rsa = self.build_rsa()?;
580        Ok(PublicEncryptingKey::new(rsa)?)
581    }
582}
583
584impl<B> AsDer<PublicKeyX509Der<'static>> for PublicKeyComponents<B>
585where
586    B: AsRef<[u8]> + Debug,
587{
588    /// Serializes the RSA public key components into an X.509 `SubjectPublicKeyInfo`
589    /// structure, as specified in [RFC 5280].
590    ///
591    /// [RFC 5280]: https://www.rfc-editor.org/rfc/rfc5280.html
592    ///
593    /// # Errors
594    /// `error::Unspecified` if the components do not form a valid RSA public key.
595    fn as_der(&self) -> Result<PublicKeyX509Der<'static>, Unspecified> {
596        let pkey = self.build_rsa()?;
597        rfc5280::encode_public_key_der(&pkey)
598    }
599}
600
601pub(super) fn generate_rsa_key(size: c_int) -> Result<LcPtr<EVP_PKEY>, Unspecified> {
602    let params_fn = |ctx| {
603        if 1 == unsafe { EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, size) } {
604            Ok(())
605        } else {
606            Err(())
607        }
608    };
609
610    LcPtr::<EVP_PKEY>::generate(EVP_PKEY_RSA, Some(params_fn))
611}
612
613#[cfg(feature = "fips")]
614#[must_use]
615pub(super) fn is_valid_fips_key(key: &LcPtr<EVP_PKEY>) -> bool {
616    // This should always be an RSA key and must-never panic.
617    let evp_pkey = key.as_const();
618    let rsa_key = evp_pkey.get_rsa().expect("RSA EVP_PKEY");
619
620    1 == unsafe { RSA_check_fips((rsa_key.as_const_ptr()).cast_mut()) }
621}
622
623pub(super) fn is_rsa_key(key: &LcPtr<EVP_PKEY>) -> bool {
624    let id = key.as_const().id();
625    id == EVP_PKEY_RSA || id == EVP_PKEY_RSA_PSS
626}
627
628pub(super) fn validate_rsa_key(key: &LcPtr<EVP_PKEY>) -> Result<(), KeyRejected> {
629    if !is_rsa_key(key) {
630        return Err(KeyRejected::unspecified());
631    }
632    match key.as_const().key_size_bits() {
633        2048..=8192 => Ok(()),
634        0..=2047 => Err(KeyRejected::too_small()),
635        _ => Err(KeyRejected::too_large()),
636    }
637}