/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 | | } |