Skip to content

Commit b265411

Browse files
committed
oaep: support non-string labels
1 parent 962b048 commit b265411

File tree

4 files changed

+40
-64
lines changed

4 files changed

+40
-64
lines changed

src/algorithms/oaep.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Encryption and Decryption using [OAEP padding](https://datatracker.ietf.org/doc/html/rfc8017#section-7.1).
22
//!
3-
use alloc::string::String;
3+
use alloc::boxed::Box;
44
use alloc::vec::Vec;
55

66
use digest::{Digest, DynDigest, FixedOutputReset};
@@ -62,7 +62,7 @@ pub(crate) fn oaep_encrypt<R: CryptoRngCore + ?Sized>(
6262
msg: &[u8],
6363
digest: &mut dyn DynDigest,
6464
mgf_digest: &mut dyn DynDigest,
65-
label: Option<String>,
65+
label: Option<Box<[u8]>>,
6666
k: usize,
6767
) -> Result<Zeroizing<Vec<u8>>> {
6868
let h_size = digest.output_size();
@@ -72,7 +72,7 @@ pub(crate) fn oaep_encrypt<R: CryptoRngCore + ?Sized>(
7272
return Err(Error::LabelTooLong);
7373
}
7474

75-
digest.update(label.as_bytes());
75+
digest.update(&label);
7676
let p_hash = digest.finalize_reset();
7777

7878
encrypt_internal(rng, msg, &p_hash, h_size, k, |seed, db| {
@@ -96,7 +96,7 @@ pub(crate) fn oaep_encrypt_digest<
9696
>(
9797
rng: &mut R,
9898
msg: &[u8],
99-
label: Option<String>,
99+
label: Option<Box<[u8]>>,
100100
k: usize,
101101
) -> Result<Zeroizing<Vec<u8>>> {
102102
let h_size = <D as Digest>::output_size();
@@ -106,7 +106,7 @@ pub(crate) fn oaep_encrypt_digest<
106106
return Err(Error::LabelTooLong);
107107
}
108108

109-
let p_hash = D::digest(label.as_bytes());
109+
let p_hash = D::digest(&label);
110110

111111
encrypt_internal(rng, msg, &p_hash, h_size, k, |seed, db| {
112112
let mut mgf_digest = MGD::new();
@@ -130,7 +130,7 @@ pub(crate) fn oaep_decrypt(
130130
em: &mut [u8],
131131
digest: &mut dyn DynDigest,
132132
mgf_digest: &mut dyn DynDigest,
133-
label: Option<String>,
133+
label: Option<Box<[u8]>>,
134134
k: usize,
135135
) -> Result<Vec<u8>> {
136136
let h_size = digest.output_size();
@@ -140,7 +140,7 @@ pub(crate) fn oaep_decrypt(
140140
return Err(Error::Decryption);
141141
}
142142

143-
digest.update(label.as_bytes());
143+
digest.update(&label);
144144

145145
let expected_p_hash = digest.finalize_reset();
146146

@@ -170,7 +170,7 @@ pub(crate) fn oaep_decrypt(
170170
#[inline]
171171
pub(crate) fn oaep_decrypt_digest<D: Digest, MGD: Digest + FixedOutputReset>(
172172
em: &mut [u8],
173-
label: Option<String>,
173+
label: Option<Box<[u8]>>,
174174
k: usize,
175175
) -> Result<Vec<u8>> {
176176
let h_size = <D as Digest>::output_size();
@@ -180,7 +180,7 @@ pub(crate) fn oaep_decrypt_digest<D: Digest, MGD: Digest + FixedOutputReset>(
180180
return Err(Error::LabelTooLong);
181181
}
182182

183-
let expected_p_hash = D::digest(label.as_bytes());
183+
let expected_p_hash = D::digest(&label);
184184

185185
let res = decrypt_inner(em, h_size, &expected_p_hash, k, |seed, db| {
186186
let mut mgf_digest = MGD::new();

src/oaep.rs

+20-28
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ mod encrypting_key;
1010
pub use self::{decrypting_key::DecryptingKey, encrypting_key::EncryptingKey};
1111

1212
use alloc::boxed::Box;
13-
use alloc::string::{String, ToString};
1413
use alloc::vec::Vec;
1514
use core::fmt;
1615

@@ -45,7 +44,7 @@ pub struct Oaep {
4544
pub mgf_digest: Box<dyn DynDigest + Send + Sync>,
4645

4746
/// Optional label.
48-
pub label: Option<String>,
47+
pub label: Option<Box<[u8]>>,
4948
}
5049

5150
impl Oaep {
@@ -75,13 +74,13 @@ impl Oaep {
7574
}
7675

7776
/// Create a new OAEP `PaddingScheme` with an associated `label`, using `T` as the hash function for both the label and for MGF1.
78-
pub fn new_with_label<T: 'static + Digest + DynDigest + Send + Sync, S: AsRef<str>>(
77+
pub fn new_with_label<T: 'static + Digest + DynDigest + Send + Sync, S: Into<Box<[u8]>>>(
7978
label: S,
8079
) -> Self {
8180
Self {
8281
digest: Box::new(T::new()),
8382
mgf_digest: Box::new(T::new()),
84-
label: Some(label.as_ref().to_string()),
83+
label: Some(label.into()),
8584
}
8685
}
8786

@@ -118,14 +117,14 @@ impl Oaep {
118117
pub fn new_with_mgf_hash_and_label<
119118
T: 'static + Digest + DynDigest + Send + Sync,
120119
U: 'static + Digest + DynDigest + Send + Sync,
121-
S: AsRef<str>,
120+
S: Into<Box<[u8]>>,
122121
>(
123122
label: S,
124123
) -> Self {
125124
Self {
126125
digest: Box::new(T::new()),
127126
mgf_digest: Box::new(U::new()),
128-
label: Some(label.as_ref().to_string()),
127+
label: Some(label.into()),
129128
}
130129
}
131130
}
@@ -188,7 +187,7 @@ fn encrypt<R: CryptoRngCore + ?Sized>(
188187
msg: &[u8],
189188
digest: &mut dyn DynDigest,
190189
mgf_digest: &mut dyn DynDigest,
191-
label: Option<String>,
190+
label: Option<Box<[u8]>>,
192191
) -> Result<Vec<u8>> {
193192
key::check_public(pub_key)?;
194193

@@ -209,7 +208,7 @@ fn encrypt_digest<R: CryptoRngCore + ?Sized, D: Digest, MGD: Digest + FixedOutpu
209208
rng: &mut R,
210209
pub_key: &RsaPublicKey,
211210
msg: &[u8],
212-
label: Option<String>,
211+
label: Option<Box<[u8]>>,
213212
) -> Result<Vec<u8>> {
214213
key::check_public(pub_key)?;
215214

@@ -238,7 +237,7 @@ fn decrypt<R: CryptoRngCore + ?Sized>(
238237
ciphertext: &[u8],
239238
digest: &mut dyn DynDigest,
240239
mgf_digest: &mut dyn DynDigest,
241-
label: Option<String>,
240+
label: Option<Box<[u8]>>,
242241
) -> Result<Vec<u8>> {
243242
if ciphertext.len() != priv_key.size() {
244243
return Err(Error::Decryption);
@@ -267,7 +266,7 @@ fn decrypt_digest<R: CryptoRngCore + ?Sized, D: Digest, MGD: Digest + FixedOutpu
267266
rng: Option<&mut R>,
268267
priv_key: &RsaPrivateKey,
269268
ciphertext: &[u8],
270-
label: Option<String>,
269+
label: Option<Box<[u8]>>,
271270
) -> Result<Vec<u8>> {
272271
key::check_public(priv_key)?;
273272

@@ -288,7 +287,6 @@ mod tests {
288287
use crate::traits::PublicKeyParts;
289288
use crate::traits::{Decryptor, RandomizedDecryptor, RandomizedEncryptor};
290289

291-
use alloc::string::String;
292290
use digest::{Digest, DynDigest, FixedOutputReset};
293291
use num_bigint::BigUint;
294292
use num_traits::FromPrimitive;
@@ -362,18 +360,12 @@ mod tests {
362360
do_test_oaep_with_different_hashes::<Sha3_512, Sha1>(&priv_key);
363361
}
364362

365-
fn get_label(rng: &mut ChaCha8Rng) -> Option<String> {
366-
const GEN_ASCII_STR_CHARSET: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
367-
abcdefghijklmnopqrstuvwxyz\
368-
0123456789=+";
369-
363+
fn get_label(rng: &mut ChaCha8Rng) -> Option<Box<[u8]>> {
370364
let mut buf = [0u8; 32];
371365
rng.fill_bytes(&mut buf);
372-
if buf[0] < (1 << 7) {
373-
for v in buf.iter_mut() {
374-
*v = GEN_ASCII_STR_CHARSET[(*v >> 2) as usize];
375-
}
376-
Some(core::str::from_utf8(&buf).unwrap().to_string())
366+
367+
if rng.next_u32() % 2 == 0 {
368+
Some(buf.into())
377369
} else {
378370
None
379371
}
@@ -398,7 +390,7 @@ mod tests {
398390
let pub_key: RsaPublicKey = prk.into();
399391

400392
let ciphertext = if let Some(ref label) = label {
401-
let padding = Oaep::new_with_label::<D, _>(label);
393+
let padding = Oaep::new_with_label::<D, _>(label.clone());
402394
pub_key.encrypt(&mut rng, padding, &input).unwrap()
403395
} else {
404396
let padding = Oaep::new::<D>();
@@ -408,8 +400,8 @@ mod tests {
408400
assert_ne!(input, ciphertext);
409401
let blind: bool = rng.next_u32() < (1 << 31);
410402

411-
let padding = if let Some(ref label) = label {
412-
Oaep::new_with_label::<D, _>(label)
403+
let padding = if let Some(label) = label {
404+
Oaep::new_with_label::<D, Box<[u8]>>(label)
413405
} else {
414406
Oaep::new::<D>()
415407
};
@@ -446,7 +438,7 @@ mod tests {
446438
let pub_key: RsaPublicKey = prk.into();
447439

448440
let ciphertext = if let Some(ref label) = label {
449-
let padding = Oaep::new_with_mgf_hash_and_label::<D, U, _>(label);
441+
let padding = Oaep::new_with_mgf_hash_and_label::<D, U, _>(label.clone());
450442
pub_key.encrypt(&mut rng, padding, &input).unwrap()
451443
} else {
452444
let padding = Oaep::new_with_mgf_hash::<D, U>();
@@ -456,7 +448,7 @@ mod tests {
456448
assert_ne!(input, ciphertext);
457449
let blind: bool = rng.next_u32() < (1 << 31);
458450

459-
let padding = if let Some(ref label) = label {
451+
let padding = if let Some(label) = label {
460452
Oaep::new_with_mgf_hash_and_label::<D, U, _>(label)
461453
} else {
462454
Oaep::new_with_mgf_hash::<D, U>()
@@ -484,7 +476,7 @@ mod tests {
484476
priv_key
485477
.decrypt_blinded(
486478
&mut rng,
487-
Oaep::new_with_label::<Sha1, _>("label"),
479+
Oaep::new_with_label::<Sha1, _>("label".as_bytes()),
488480
&ciphertext,
489481
)
490482
.is_err(),
@@ -572,7 +564,7 @@ mod tests {
572564
let priv_key = get_private_key();
573565
let pub_key: RsaPublicKey = (&priv_key).into();
574566
let encrypting_key = EncryptingKey::<Sha1>::new(pub_key);
575-
let decrypting_key = DecryptingKey::<Sha1>::new_with_label(priv_key, "label");
567+
let decrypting_key = DecryptingKey::<Sha1>::new_with_label(priv_key, "label".as_bytes());
576568
let ciphertext = encrypting_key
577569
.encrypt_with_rng(&mut rng, "a_plain_text".as_bytes())
578570
.unwrap();

src/oaep/decrypting_key.rs

+6-19
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ use crate::{
44
traits::{Decryptor, RandomizedDecryptor},
55
Result, RsaPrivateKey,
66
};
7-
use alloc::{
8-
string::{String, ToString},
9-
vec::Vec,
10-
};
7+
use alloc::{boxed::Box, vec::Vec};
118
use core::marker::PhantomData;
129
use digest::{Digest, FixedOutputReset};
1310
use rand_core::CryptoRngCore;
@@ -26,7 +23,7 @@ where
2623
MGD: Digest + FixedOutputReset,
2724
{
2825
inner: RsaPrivateKey,
29-
label: Option<String>,
26+
label: Option<Box<[u8]>>,
3027
phantom: PhantomData<D>,
3128
mg_phantom: PhantomData<MGD>,
3229
}
@@ -47,10 +44,10 @@ where
4744
}
4845

4946
/// Create a new verifying key from an RSA public key using provided label
50-
pub fn new_with_label<S: AsRef<str>>(key: RsaPrivateKey, label: S) -> Self {
47+
pub fn new_with_label<S: Into<Box<[u8]>>>(key: RsaPrivateKey, label: S) -> Self {
5148
Self {
5249
inner: key,
53-
label: Some(label.as_ref().to_string()),
50+
label: Some(label.into()),
5451
phantom: Default::default(),
5552
mg_phantom: Default::default(),
5653
}
@@ -63,12 +60,7 @@ where
6360
MGD: Digest + FixedOutputReset,
6461
{
6562
fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>> {
66-
decrypt_digest::<DummyRng, D, MGD>(
67-
None,
68-
&self.inner,
69-
ciphertext,
70-
self.label.as_ref().cloned(),
71-
)
63+
decrypt_digest::<DummyRng, D, MGD>(None, &self.inner, ciphertext, self.label.clone())
7264
}
7365
}
7466

@@ -82,12 +74,7 @@ where
8274
rng: &mut R,
8375
ciphertext: &[u8],
8476
) -> Result<Vec<u8>> {
85-
decrypt_digest::<_, D, MGD>(
86-
Some(rng),
87-
&self.inner,
88-
ciphertext,
89-
self.label.as_ref().cloned(),
90-
)
77+
decrypt_digest::<_, D, MGD>(Some(rng), &self.inner, ciphertext, self.label.clone())
9178
}
9279
}
9380

src/oaep/encrypting_key.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use super::encrypt_digest;
22
use crate::{traits::RandomizedEncryptor, Result, RsaPublicKey};
3-
use alloc::{
4-
string::{String, ToString},
5-
vec::Vec,
6-
};
3+
use alloc::{boxed::Box, vec::Vec};
74
use core::marker::PhantomData;
85
use digest::{Digest, FixedOutputReset};
96
use rand_core::CryptoRngCore;
@@ -21,7 +18,7 @@ where
2118
MGD: Digest + FixedOutputReset,
2219
{
2320
inner: RsaPublicKey,
24-
label: Option<String>,
21+
label: Option<Box<[u8]>>,
2522
phantom: PhantomData<D>,
2623
mg_phantom: PhantomData<MGD>,
2724
}
@@ -42,10 +39,10 @@ where
4239
}
4340

4441
/// Create a new verifying key from an RSA public key using provided label
45-
pub fn new_with_label<S: AsRef<str>>(key: RsaPublicKey, label: S) -> Self {
42+
pub fn new_with_label<S: Into<Box<[u8]>>>(key: RsaPublicKey, label: S) -> Self {
4643
Self {
4744
inner: key,
48-
label: Some(label.as_ref().to_string()),
45+
label: Some(label.into()),
4946
phantom: Default::default(),
5047
mg_phantom: Default::default(),
5148
}
@@ -62,7 +59,7 @@ where
6259
rng: &mut R,
6360
msg: &[u8],
6461
) -> Result<Vec<u8>> {
65-
encrypt_digest::<_, D, MGD>(rng, &self.inner, msg, self.label.as_ref().cloned())
62+
encrypt_digest::<_, D, MGD>(rng, &self.inner, msg, self.label.clone())
6663
}
6764
}
6865

0 commit comments

Comments
 (0)