Coverage Report

Created: 2025-12-31 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/spdm-rs/external/ring/src/rsa/public_modulus.rs
Line
Count
Source
1
use crate::{
2
    arithmetic::{bigint, montgomery::RR},
3
    bits::{self, FromByteLen as _},
4
    cpu,
5
    error::{self, InputTooLongError},
6
    rsa::N,
7
};
8
use core::ops::RangeInclusive;
9
10
/// The modulus (n) of an RSA public key.
11
pub struct PublicModulus {
12
    value: bigint::OwnedModulus<N>,
13
    oneRR: bigint::One<N, RR>,
14
}
15
16
impl Clone for PublicModulus {
17
0
    fn clone(&self) -> Self {
18
0
        let PublicModulus { value, oneRR } = self;
19
0
        let value = value.clone();
20
21
        // XXX: Shouldn't really be needed just to call `alloc_zero()`,
22
        // but not worth optimizing away.
23
0
        let cpu = cpu::features();
24
0
        let n = value.modulus(cpu);
25
0
        let oneRR = oneRR.clone_into(n.alloc_zero());
26
27
0
        Self { value, oneRR }
28
0
    }
29
}
30
31
/*
32
impl core::fmt::Debug for PublicModulus {
33
    fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
34
        self.value.fmt(fmt)
35
    }
36
}*/
37
38
impl PublicModulus {
39
0
    pub(super) fn from_be_bytes(
40
0
        n: untrusted::Input,
41
0
        allowed_bit_lengths: RangeInclusive<bits::BitLength>,
42
0
        cpu_features: cpu::Features,
43
0
    ) -> Result<Self, error::KeyRejected> {
44
        // See `PublicKey::from_modulus_and_exponent` for background on the step
45
        // numbering.
46
47
0
        let min_bits = *allowed_bit_lengths.start();
48
0
        let max_bits = *allowed_bit_lengths.end();
49
50
        // `pkcs1_encode` depends on this not being small. Otherwise,
51
        // `pkcs1_encode` would generate padding that is invalid (too few 0xFF
52
        // bytes) for very small keys.
53
        const MIN_BITS: bits::BitLength = bits::BitLength::from_bits(1024);
54
55
        // Step 3 / Step c for `n` (out of order).
56
0
        let value = bigint::OwnedModulusValue::from_be_bytes(n)?;
57
0
        let bits = value.len_bits();
58
59
        // Step 1 / Step a. XXX: SP800-56Br1 and SP800-89 require the length of
60
        // the public modulus to be exactly 2048 or 3072 bits, but we are more
61
        // flexible to be compatible with other commonly-used crypto libraries.
62
0
        assert!(min_bits >= MIN_BITS);
63
0
        let bits_rounded_up = bits::BitLength::from_byte_len(bits.as_usize_bytes_rounded_up())
64
0
            .map_err(error::erase::<InputTooLongError>)
65
0
            .unwrap(); // TODO: safe?
66
0
        if bits_rounded_up < min_bits {
67
0
            return Err(error::KeyRejected::too_small());
68
0
        }
69
0
        if bits > max_bits {
70
0
            return Err(error::KeyRejected::too_large());
71
0
        }
72
0
        let value = bigint::OwnedModulus::from(value);
73
0
        let m = value.modulus(cpu_features);
74
0
        let oneRR = bigint::One::newRR(m.alloc_zero(), &m);
75
76
0
        Ok(Self { value, oneRR })
77
0
    }
78
79
    /// The big-endian encoding of the modulus.
80
    ///
81
    /// There are no leading zeros.
82
0
    pub fn be_bytes(&self) -> impl ExactSizeIterator<Item = u8> + Clone + '_ {
83
0
        self.value.be_bytes()
84
0
    }
85
86
    /// The length of the modulus in bits.
87
0
    pub fn len_bits(&self) -> bits::BitLength {
88
0
        self.value.len_bits()
89
0
    }
90
91
0
    pub(super) fn value(&self, cpu_features: cpu::Features) -> bigint::Modulus<N> {
92
0
        self.value.modulus(cpu_features)
93
0
    }
94
95
0
    pub(super) fn oneRR(&self) -> &bigint::Elem<N, RR> {
96
0
        self.oneRR.as_ref()
97
0
    }
98
}