Skip to content

Commit 9d171a6

Browse files
committed
No-std support
1 parent 02689d1 commit 9d171a6

13 files changed

+87
-47
lines changed

.travis.yml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ matrix:
1010
script:
1111
- if [[ "$TRAVIS_NIGHTLY" == "true" ]]; then cargo test --verbose --all-features; fi
1212
- if [[ "$TRAVIS_NIGHTLY" == "true" ]]; then cargo bench --verbose --all-features --no-run; fi
13+
- if [[ "$TRAVIS_NIGHTLY" == "true" ]]; then rustup target add thumbv7m-none-eabi; fi
14+
- if [[ "$TRAVIS_NIGHTLY" == "true" ]]; then cargo build --verbose --no-default-features --target thumbv7m-none-eabi; fi
1315
- if [[ "$TRAVIS_NIGHTLY" != "true" ]]; then cargo test --verbose; fi
1416

1517
cache: cargo

Cargo.toml

+16-16
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,17 @@ categories = ["cryptography"]
1212
readme = "README.md"
1313

1414
[dependencies]
15-
num-bigint = { version = "0.6", features = ["rand", "i128", "u64_digit", "prime", "zeroize"], package = "num-bigint-dig" }
16-
num-traits = "0.2.6"
17-
num-integer = "0.1.39"
18-
num-iter = "0.1.37"
19-
lazy_static = "1.3.0"
20-
rand = "0.7.0"
21-
byteorder = "1.3.1"
22-
thiserror = "1.0.11"
23-
subtle = "2.0.0"
24-
simple_asn1 = "0.4"
15+
num-bigint = { version = "0.6", features = ["i128", "u64_digit", "prime", "zeroize"], default-features = false, package = "num-bigint-dig" }
16+
num-traits = { version= "0.2.9", default-features = false, features = ["libm"] }
17+
num-integer = { version = "0.1.39", default-features = false }
18+
num-iter = { version = "0.1.37", default-features = false }
19+
lazy_static = { version = "1.3.0", features = ["spin_no_std"] }
20+
rand = { version = "0.7.0", default-features = false }
21+
byteorder = { version = "1.3.1", default-features = false }
22+
subtle = { version = "2.0.0", default-features = false }
23+
simple_asn1 = { version = "0.4", optional = true }
2524
pem = { version = "0.8", optional = true }
26-
digest = { version = "0.9.0", features = ["std"] }
27-
sha2 = "0.9.0"
25+
digest = { version = "0.9.0", default-features = false }
2826

2927
[dependencies.zeroize]
3028
version = "1.1.0"
@@ -35,16 +33,16 @@ package = "serde"
3533
optional = true
3634
version = "1.0.89"
3735
default-features = false
38-
features = ["std", "derive"]
36+
features = ["derive"]
3937

4038
[dev-dependencies]
4139
base64 = "0.12.0"
4240
hex = "0.4.0"
4341
serde_test = "1.0.89"
4442
rand_xorshift = "0.2.0"
4543
pem = "0.8"
46-
sha-1 = "0.9.0"
47-
sha3 = "0.9.0"
44+
#sha-1 = "0.9.0"
45+
#sha3 = "0.9.0"
4846

4947
[[bench]]
5048
name = "key"
@@ -56,8 +54,10 @@ name = "key"
5654
# debug = true
5755

5856
[features]
59-
default = ["pem"]
57+
default = ["std", "pem"]
6058
nightly = ["subtle/nightly", "num-bigint/nightly"]
6159
serde = ["num-bigint/serde", "serde_crate"]
6260
serde1 = ["serde"] # deprecated
6361
expose-internals = []
62+
std = ["alloc", "simple_asn1", "digest/std"]
63+
alloc = ["digest/alloc"]

src/algorithms.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use digest::DynDigest;
22
use num_bigint::traits::ModInverse;
33
use num_bigint::{BigUint, RandPrime};
44
use num_traits::{FromPrimitive, One, Zero};
5+
#[cfg(not(feature = "std"))]
6+
use num_traits::{Float};
57
use rand::Rng;
8+
use alloc::vec;
69

710
use crate::errors::{Error, Result};
811
use crate::key::RSAPrivateKey;
@@ -119,7 +122,7 @@ pub fn mgf1_xor(out: &mut [u8], digest: &mut dyn DynDigest, seed: &[u8]) {
119122
let mut counter = [0u8; 4];
120123
let mut i = 0;
121124

122-
const MAX_LEN: u64 = std::u32::MAX as u64 + 1;
125+
const MAX_LEN: u64 = core::u32::MAX as u64 + 1;
123126
assert!(out.len() as u64 <= MAX_LEN);
124127

125128
while i < out.len() {

src/errors.rs

+28-19
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,49 @@
1-
use thiserror::Error;
1+
use alloc::string::String;
22

3-
pub type Result<T> = ::std::result::Result<T, Error>;
3+
pub type Result<T> = core::result::Result<T, Error>;
44

55
/// Error types
6-
#[derive(Debug, Error)]
6+
#[derive(Debug)]
77
pub enum Error {
8-
#[error("invalid padding scheme")]
98
InvalidPaddingScheme,
10-
#[error("decryption error")]
119
Decryption,
12-
#[error("verification error")]
1310
Verification,
14-
#[error("message too long")]
1511
MessageTooLong,
16-
#[error("input must be hashed")]
1712
InputNotHashed,
18-
#[error("nprimes must be >= 2")]
1913
NprimesTooSmall,
20-
#[error("too few primes of given length to generate an RSA key")]
2114
TooFewPrimes,
22-
#[error("invalid prime value")]
2315
InvalidPrime,
24-
#[error("invalid modulus")]
2516
InvalidModulus,
26-
#[error("invalid exponent")]
2717
InvalidExponent,
28-
#[error("invalid coefficient")]
2918
InvalidCoefficient,
30-
#[error("public exponent too small")]
3119
PublicExponentTooSmall,
32-
#[error("public exponent too large")]
3320
PublicExponentTooLarge,
34-
#[error("parse error: {}", reason)]
3521
ParseError { reason: String },
36-
#[error("internal error")]
3722
Internal,
38-
#[error("label too long")]
3923
LabelTooLong,
4024
}
25+
26+
#[cfg(feature = "std")]
27+
impl std::error::Error for Error {}
28+
impl core::fmt::Display for Error {
29+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
30+
match self {
31+
Error::InvalidPaddingScheme => write!(f, "invalid padding scheme"),
32+
Error::Decryption => write!(f, "decryption error"),
33+
Error::Verification => write!(f, "verification error"),
34+
Error::MessageTooLong => write!(f, "message too long"),
35+
Error::InputNotHashed => write!(f, "input must be hashed"),
36+
Error::NprimesTooSmall => write!(f, "nprimes must be >= 2"),
37+
Error::TooFewPrimes => write!(f, "too few primes of given length to generate an RSA key"),
38+
Error::InvalidPrime => write!(f, "invalid prime value"),
39+
Error::InvalidModulus => write!(f, "invalid modulus"),
40+
Error::InvalidExponent => write!(f, "invalid exponent"),
41+
Error::InvalidCoefficient => write!(f, "invalid coefficient"),
42+
Error::PublicExponentTooSmall => write!(f, "public exponent too small"),
43+
Error::PublicExponentTooLarge => write!(f, "public exponent too large"),
44+
Error::ParseError { reason } => write!(f, "parse error: {}", reason),
45+
Error::Internal => write!(f, "internal error"),
46+
Error::LabelTooLong => write!(f, "label too long"),
47+
}
48+
}
49+
}

src/internals.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use num_bigint::{BigInt, BigUint, IntoBigInt, IntoBigUint, ModInverse, RandBigInt, ToBigInt};
22
use num_traits::{One, Signed, Zero};
33
use rand::Rng;
4-
use std::borrow::Cow;
4+
use alloc::borrow::Cow;
55
use zeroize::Zeroize;
6+
use alloc::vec::Vec;
7+
use alloc::vec;
68

79
use crate::errors::{Error, Result};
810
use crate::key::{PublicKeyParts, RSAPrivateKey};

src/key.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ use num_bigint::traits::ModInverse;
22
use num_bigint::Sign::Plus;
33
use num_bigint::{BigInt, BigUint};
44
use num_traits::{FromPrimitive, One};
5-
use rand::{rngs::ThreadRng, Rng};
5+
use rand::{rngs::StdRng, Rng};
66
#[cfg(feature = "serde")]
77
use serde_crate::{Deserialize, Serialize};
8-
use std::ops::Deref;
8+
use core::ops::Deref;
99
use zeroize::Zeroize;
10+
use alloc::vec::Vec;
1011

1112
use crate::algorithms::generate_multi_prime_key;
1213
use crate::errors::{Error, Result};
@@ -247,6 +248,7 @@ impl RSAPublicKey {
247248
/// let der_bytes = base64::decode(&der_encoded).expect("failed to decode base64 content");
248249
/// let public_key = RSAPublicKey::from_pkcs1(&der_bytes).expect("failed to parse key");
249250
/// ```
251+
#[cfg(feature = "std")]
250252
pub fn from_pkcs1(der: &[u8]) -> Result<RSAPublicKey> {
251253
crate::parse::parse_public_key_pkcs1(der)
252254
}
@@ -281,6 +283,7 @@ impl RSAPublicKey {
281283
/// let der_bytes = base64::decode(&der_encoded).expect("failed to decode base64 content");
282284
/// let public_key = RSAPublicKey::from_pkcs8(&der_bytes).expect("failed to parse key");
283285
/// ```
286+
#[cfg(feature = "std")]
284287
pub fn from_pkcs8(der: &[u8]) -> Result<RSAPublicKey> {
285288
crate::parse::parse_public_key_pkcs8(der)
286289
}
@@ -393,6 +396,7 @@ impl RSAPrivateKey {
393396
/// let der_bytes = base64::decode(&der_encoded).expect("failed to decode base64 content");
394397
/// let private_key = RSAPrivateKey::from_pkcs1(&der_bytes).expect("failed to parse key");
395398
/// ```
399+
#[cfg(feature = "std")]
396400
pub fn from_pkcs1(der: &[u8]) -> Result<RSAPrivateKey> {
397401
crate::parse::parse_private_key_pkcs1(der)
398402
}
@@ -433,6 +437,7 @@ impl RSAPrivateKey {
433437
/// let der_bytes = base64::decode(&der_encoded).expect("failed to decode base64 content");
434438
/// let private_key = RSAPrivateKey::from_pkcs8(&der_bytes).expect("failed to parse key");
435439
/// ```
440+
#[cfg(feature = "std")]
436441
pub fn from_pkcs8(der: &[u8]) -> Result<RSAPrivateKey> {
437442
crate::parse::parse_private_key_pkcs8(der)
438443
}
@@ -542,10 +547,10 @@ impl RSAPrivateKey {
542547
match padding {
543548
// need to pass any Rng as the type arg, so the type checker is happy, it is not actually used for anything
544549
PaddingScheme::PKCS1v15Encrypt => {
545-
pkcs1v15::decrypt::<ThreadRng, _>(None, self, ciphertext)
550+
pkcs1v15::decrypt::<StdRng, _>(None, self, ciphertext)
546551
}
547552
PaddingScheme::OAEP { mut digest, label } => {
548-
oaep::decrypt::<ThreadRng, _>(None, self, ciphertext, &mut *digest, label)
553+
oaep::decrypt::<StdRng, _>(None, self, ciphertext, &mut *digest, label)
549554
}
550555
_ => Err(Error::InvalidPaddingScheme),
551556
}
@@ -572,14 +577,15 @@ impl RSAPrivateKey {
572577
/// Sign the given digest.
573578
pub fn sign(&self, padding: PaddingScheme, digest_in: &[u8]) -> Result<Vec<u8>> {
574579
match padding {
580+
// need to pass any Rng as the type arg, so the type checker is happy, it is not actually used for anything
575581
PaddingScheme::PKCS1v15Sign { ref hash } => {
576-
pkcs1v15::sign::<ThreadRng, _>(None, self, hash.as_ref(), digest_in)
582+
pkcs1v15::sign::<StdRng, _>(None, self, hash.as_ref(), digest_in)
577583
}
578584
PaddingScheme::PSS {
579585
mut salt_rng,
580586
mut digest,
581587
salt_len,
582-
} => pss::sign::<_, ThreadRng, _>(
588+
} => pss::sign::<_, StdRng, _>(
583589
&mut *salt_rng,
584590
None,
585591
self,

src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@
4747
//! let dec_data = private_key.decrypt(padding, &enc_data).expect("failed to decrypt");
4848
//! assert_eq!(&data[..], &dec_data[..]);
4949
//! ```
50+
#![no_std]
51+
52+
#[cfg(feature = "alloc")]
53+
extern crate alloc;
54+
#[cfg(feature = "std")]
55+
extern crate std;
5056

5157
#[macro_use]
5258
extern crate lazy_static;
@@ -80,6 +86,7 @@ pub use pem;
8086

8187
mod key;
8288
mod oaep;
89+
#[cfg(feature = "std")]
8390
mod parse;
8491
mod pkcs1v15;
8592
mod pss;

src/oaep.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
use rand::Rng;
2+
use alloc::vec;
3+
use alloc::vec::Vec;
4+
use alloc::string::String;
25

36
use digest::DynDigest;
47
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};

src/padding.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use std::fmt;
1+
use core::fmt;
2+
use alloc::string::{String, ToString};
3+
use alloc::boxed::Box;
24

35
use digest::{Digest, DynDigest};
46
use rand::RngCore;

src/parse.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ use crate::{
33
RSAPrivateKey, RSAPublicKey,
44
};
55
use simple_asn1::{ASN1Block, ASN1DecodeErr, BigUint, OID};
6-
7-
use std::convert::TryFrom;
6+
use alloc::format;
7+
use alloc::vec;
8+
use alloc::vec::Vec;
9+
use core::convert::TryFrom;
810

911
impl From<ASN1DecodeErr> for Error {
1012
fn from(e: ASN1DecodeErr) -> Error {

src/pkcs1v15.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use rand::Rng;
22
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
3+
use alloc::vec;
4+
use alloc::vec::Vec;
35

46
use crate::errors::{Error, Result};
57
use crate::hash::Hash;

src/pss.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use std::vec::Vec;
1+
use alloc::vec;
2+
use alloc::vec::Vec;
23

34
use digest::DynDigest;
45
use rand::{Rng, RngCore};

src/raw.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use num_bigint::BigUint;
22
use rand::Rng;
33
use zeroize::Zeroize;
4+
use alloc::vec::Vec;
45

56
use crate::errors::{Error, Result};
67
use crate::internals;

0 commit comments

Comments
 (0)