Skip to main content

Crate rsa

Crate rsa 

Source
Expand description

§rsa heapless fork

CI AVR Cortex-M RISC-V

A microcontroller-friendly fork of the RustCrypto RSA crate. Public-key operations — PKCS#1 v1.5 verify, OAEP encrypt, PSS verify — are generic over the bigint backend, with a no-alloc path through fixed-bigint and modmath tested on 8-bit AVR, Cortex-M and RISC-V.

§Scope

This is a proof of concept focused on shrinking code size and stack usage. Public-key only — verification and encryption — which covers the common embedded use cases (bootloader signature checks, key wrapping to a server).

Private-key operations (key generation, signing, decryption) are deliberately omitted from the heapless path on safety grounds: doing them correctly requires constant-time primitives, a trustworthy RNG, and secure key storage that the dependency stack doesn’t yet provide. The full upstream behavior remains available via the alloc and private-key feature flags on a heap-allocating backend; license, MSRV, and security advisories there follow the upstream crate, preserved verbatim in UPSTREAM_README.md.

§Resource usage (as of version 0.10.0-rc.18)

PSS signature verification. The u8 backend uses 8-bit limbs (more portable, works on 8-bit AVR); the u32 backend uses 32-bit limbs (natural on 32-bit cores). Full sweeps across key sizes, operations, and targets live under footprint/.

TargetKeyHashBackend.text (KiB)Stack (bytes)
ATmega2560512SHA-1u827.43099
Cortex-M0512SHA-1u328.94208
Cortex-M02048SHA-256u3215.511724
Cortex-M3512SHA-1u329.24216
Cortex-M32048SHA-256u3213.111564
sifive_e (RV32)512SHA-1u3211.32840
sifive_e (RV32)2048SHA-256u3221.111736
§Example (host, alloc)
use rsa::{Pkcs1v15Encrypt, RsaPublicKey};
let pub_key: RsaPublicKey = /* parse from DER/PEM via pkcs1/pkcs8 */;
let mut rng = rand::rng();
let enc = pub_key.encrypt(&mut rng, Pkcs1v15Encrypt, b"hello").unwrap();

For no-alloc usage (embedded), see the examples/ and footprint/ directories.

§Supported algorithms

This crate supports several schemes described in RFC8017:

These schemes are described below.

§Usage

§OAEP encryption

Note: requires sha2 feature of rsa crate is enabled.

use rsa::{RsaPrivateKey, RsaPublicKey, Oaep, sha2::Sha256};

let mut rng = rand::rng();

let bits = 2048;
let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
let public_key = RsaPublicKey::from(&private_key);

// Encrypt
let data = b"hello world";
let padding = Oaep::<Sha256>::new();
let enc_data = public_key.encrypt(&mut rng, padding, &data[..]).expect("failed to encrypt");
assert_ne!(&data[..], &enc_data[..]);

// Decrypt
let padding = Oaep::<Sha256>::new();
let dec_data = private_key.decrypt(padding, &enc_data).expect("failed to decrypt");
assert_eq!(&data[..], &dec_data[..]);

§PKCS#1 v1.5 encryption

Warning: See security notes in the pkcs1v15 module.
use rsa::{RsaPrivateKey, RsaPublicKey, Pkcs1v15Encrypt};

let mut rng = rand::rng();

let bits = 2048;
let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
let public_key = RsaPublicKey::from(&private_key);

// Encrypt
let data = b"hello world";
let enc_data = public_key.encrypt(&mut rng, Pkcs1v15Encrypt, &data[..]).expect("failed to encrypt");
assert_ne!(&data[..], &enc_data[..]);

// Decrypt
let dec_data = private_key.decrypt(Pkcs1v15Encrypt, &enc_data).expect("failed to decrypt");
assert_eq!(&data[..], &dec_data[..]);

§PKCS#1 v1.5 signatures

Warning: See security notes in the pkcs1v15 module.

Note: requires sha2 feature of rsa crate is enabled.

use rsa::RsaPrivateKey;
use rsa::pkcs1v15::{SigningKey, VerifyingKey};
use rsa::signature::{Keypair, RandomizedSigner, SignatureEncoding, Verifier};
use rsa::sha2::{Digest, Sha256};

let mut rng = rand::rng();

let bits = 2048;
let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
let signing_key = SigningKey::<Sha256>::new(private_key);
let verifying_key = signing_key.verifying_key();

// Sign
let data = b"hello world";
let signature = signing_key.sign_with_rng(&mut rng, data);
assert_ne!(signature.to_bytes().as_ref(), data.as_slice());

// Verify
verifying_key.verify(data, &signature).expect("failed to verify");

§PSS signatures

Note: requires sha2 feature of rsa crate is enabled.

use rsa::RsaPrivateKey;
use rsa::pss::{BlindedSigningKey, VerifyingKey};
use rsa::signature::{Keypair,RandomizedSigner, SignatureEncoding, Verifier};
use rsa::sha2::{Digest, Sha256};

let mut rng = rand::rng();

let bits = 2048;
let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
let signing_key = BlindedSigningKey::<Sha256>::new(private_key);
let verifying_key = signing_key.verifying_key();

// Sign
let data = b"hello world";
let signature = signing_key.sign_with_rng(&mut rng, data);
assert_ne!(signature.to_bytes().as_ref(), data);

// Verify
verifying_key.verify(data, &signature).expect("failed to verify");

§PKCS#1 RSA Key Encoding

PKCS#1 supports a legacy format for encoding RSA keys as binary (DER) or text (PEM) data.

You can recognize PEM encoded PKCS#1 keys because they have “RSA * KEY” in the type label, e.g.:

-----BEGIN RSA PRIVATE KEY-----

Most modern applications use the newer PKCS#8 format instead (see below).

The following traits can be used to decode/encode RsaPrivateKey and RsaPublicKey as PKCS#1. Note that pkcs1 is re-exported from the toplevel of the rsa crate:

§Example

use rsa::{RsaPublicKey, pkcs1::DecodeRsaPublicKey};

let pem = "-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAtsQsUV8QpqrygsY+2+JCQ6Fw8/omM71IM2N/R8pPbzbgOl0p78MZ
GsgPOQ2HSznjD0FPzsH8oO2B5Uftws04LHb2HJAYlz25+lN5cqfHAfa3fgmC38Ff
wBkn7l582UtPWZ/wcBOnyCgb3yLcvJrXyrt8QxHJgvWO23ITrUVYszImbXQ67YGS
0YhMrbixRzmo2tpm3JcIBtnHrEUMsT0NfFdfsZhTT8YbxBvA8FdODgEwx7u/vf3J
9qbi4+Kv8cvqyJuleIRSjVXPsIMnoejIn04APPKIjpMyQdnWlby7rNyQtE4+CV+j
cFjqJbE/Xilcvqxt6DirjFCvYeKYl1uHLwIDAQAB
-----END RSA PUBLIC KEY-----";

let public_key = RsaPublicKey::from_pkcs1_pem(pem)?;

§PKCS#8 RSA Key Encoding

PKCS#8 is a private key format with support for multiple algorithms. Like PKCS#1, it can be encoded as binary (DER) or text (PEM).

You can recognize PEM encoded PKCS#8 keys because they don’t have an algorithm name in the type label, e.g.:

-----BEGIN PRIVATE KEY-----

The following traits can be used to decode/encode RsaPrivateKey and RsaPublicKey as PKCS#8. Note that pkcs8 is re-exported from the toplevel of the rsa crate:

§Example

use rsa::{RsaPublicKey, pkcs8::DecodePublicKey};

let pem = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtsQsUV8QpqrygsY+2+JC
Q6Fw8/omM71IM2N/R8pPbzbgOl0p78MZGsgPOQ2HSznjD0FPzsH8oO2B5Uftws04
LHb2HJAYlz25+lN5cqfHAfa3fgmC38FfwBkn7l582UtPWZ/wcBOnyCgb3yLcvJrX
yrt8QxHJgvWO23ITrUVYszImbXQ67YGS0YhMrbixRzmo2tpm3JcIBtnHrEUMsT0N
fFdfsZhTT8YbxBvA8FdODgEwx7u/vf3J9qbi4+Kv8cvqyJuleIRSjVXPsIMnoejI
n04APPKIjpMyQdnWlby7rNyQtE4+CV+jcFjqJbE/Xilcvqxt6DirjFCvYeKYl1uH
LwIDAQAB
-----END PUBLIC KEY-----";

let public_key = RsaPublicKey::from_public_key_pem(pem)?;

Re-exports§

pub use crate::modmath_support::ModMathForm;modmath
pub use crate::modmath_support::ModMathInt;modmath
pub use crate::modmath_support::ModMathIntCt;modmath
pub use crate::modmath_support::ModMathParams;modmath
pub use crate::modmath_support::ModMathValue;modmath
pub use crate::errors::Error;
pub use crate::errors::Result;
pub use crate::pkcs1v15::Pkcs1v15Encrypt;
pub use crate::pkcs1v15::Pkcs1v15Sign;
pub use crate::oaep::Oaep;alloc
pub use crate::pss::Pss;alloc
pub use rand_core;
pub use signature;
pub use pkcs1;encoding
pub use pkcs8;encoding
pub use sha2;sha2

Modules§

errors
Error types.
hazmatalloc and hazmat
⚠️ Low-level “hazmat” RSA functions.
modmath_supportmodmath
Generic modmath backend adapters for fixed-width RSA public-key paths.
oaep
Encryption and Decryption using OAEP padding.
pkcs1v15
PKCS#1 v1.5 support as described in RFC8017 § 8.2.
pss
Support for the Probabilistic Signature Scheme (PSS) a.k.a. RSASSA-PSS.
traits
RSA-related trait definitions.

Structs§

BoxedUintalloc
Fixed-precision heap-allocated big unsigned integer.
CrtValuealloc and private-key
Contains the precomputed Chinese remainder theorem values.
Ctmodmath
Constant-time marker.
GenericRsaPublicKey
Represents the public part of an RSA key.
Nctmodmath
Non-constant-time marker. Default personality for [FixedUInt].
RsaPrivateKeyprivate-key
Represents a whole RSA key, public and private parts.

Type Aliases§

RsaPublicKeyalloc
Boxed RSA public key alias used by the alloc code path. Equivalent to GenericRsaPublicKey<BoxedUint, BoxedMontyParams>.