Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .codespellexcludelines
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ rsource "Kconfig.tls-generic"
const uint8_t* hashIn, int hashSz)
XMEMCPY(hash + (curveSz - hashSz), hashIn, hashSz);
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, /* creen would be i */
0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, /* creen would be i */
\pagenumbering{alph}
DES3_KEY_SIZE = 24, /* 3 des ede */
/* functions added to support above needed, removed TOOM and KARATSUBA */
Expand Down
4 changes: 2 additions & 2 deletions wolfssl/wolfcrypt/chacha20_poly1305.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ WOLFSSL_API WARN_UNUSED_RESULT int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* ae
WOLFSSL_API int wc_XChaCha20Poly1305_Init(
ChaChaPoly_Aead* aead,
const byte *ad, word32 ad_len,
const byte *inKey, word32 inKeySz,
const byte *inIV, word32 inIVSz,
const byte *nonce, word32 nonce_len,
const byte *key, word32 key_len,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter order was incorrect for this function. I talked with @douzzer about it and updating the prototype to match the implementation made the most sense.

I originally was planning to wrap this function with a chunking API for XChaCha20-Poly1305 but ended up not needing that right now and there are not corresponding encrypt/decrypt functions for XChaCha20-Poly1305 like there are for ChaCha20-Poly1305 so I am omitting a Rust wrapper for that at the moment.

int isEncrypt);

WOLFSSL_API int wc_XChaCha20Poly1305_Encrypt(
Expand Down
7 changes: 5 additions & 2 deletions wrapper/rust/wolfssl-wolfcrypt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@ functionality:

* AES
* CBC, CCM, CFB, CTR, EAX, ECB, GCM, OFB, XTS
* BLAKE2
* CMAC
* ChaCha20-Poly1305
* Curve25519
* DH
* ECC
* Ed448
* Ed25519
* Ed448
* HKDF
* HMAC
* PBKDF2
* PKCS #12 PBKDF
* PRF
* RSA
* RNG
* RSA
* SHA
* SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA3-224, SHA3-256, SHA3-384,
SHA3-512, SHAKE128, SHAKE256
Expand Down
1 change: 1 addition & 0 deletions wrapper/rust/wolfssl-wolfcrypt/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ fn scan_cfg() -> Result<()> {

/* chacha20_poly1305 */
check_cfg(&binding, "wc_ChaCha20Poly1305_Encrypt", "chacha20_poly1305");
check_cfg(&binding, "wc_XChaCha20Poly1305_Encrypt", "xchacha20_poly1305");

/* cmac */
check_cfg(&binding, "wc_InitCmac", "cmac");
Expand Down
100 changes: 100 additions & 0 deletions wrapper/rust/wolfssl-wolfcrypt/src/chacha20_poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ pub struct ChaCha20Poly1305 {
}

impl ChaCha20Poly1305 {
/// Key size for ChaCha20-Poly1305 stream cipher.
pub const KEYSIZE: usize = sys::CHACHA20_POLY1305_AEAD_KEYSIZE as usize;
/// IV size for ChaCha20-Poly1305 stream cipher.
pub const IV_SIZE: usize = sys::CHACHA20_POLY1305_AEAD_IV_SIZE as usize;
/// Authentication tag size for ChaCha20-Poly1305 stream cipher.
pub const AUTH_TAG_SIZE: usize = sys::CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE as usize;

/// Decrypt an input message from `ciphertext` using the ChaCha20 stream
Expand Down Expand Up @@ -240,3 +243,100 @@ impl ChaCha20Poly1305 {
Ok(())
}
}

#[cfg(xchacha20_poly1305)]
pub struct XChaCha20Poly1305 {
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this struct is empty right now, if we do go back and add the streaming/chunking API for XChaCha20Poly1305, a field will be added here. I set it up to use a struct to future-proof for this and to maintain symmetry with the ChaCha20Poly1305 interface above.


#[cfg(xchacha20_poly1305)]
impl XChaCha20Poly1305 {
/// Key size for XChaCha20-Poly1305 stream cipher.
pub const KEYSIZE: usize = sys::CHACHA20_POLY1305_AEAD_KEYSIZE as usize;
/// IV size for XChaCha20-Poly1305 stream cipher.
pub const IV_SIZE: usize = sys::XCHACHA20_POLY1305_AEAD_NONCE_SIZE as usize;
/// Authentication tag size for XChaCha20-Poly1305 stream cipher.
pub const AUTH_TAG_SIZE: usize = sys::CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE as usize;

/// Decrypt an input message from `ciphertext` using the XChaCha20 stream
/// cipher into the `plaintext` output buffer. It also performs Poly-1305
/// authentication. The authentication tag is expected to be located in the
/// last 16 bytes of the `ciphertext` buffer.
/// If Err is returned, the output data, `plaintext` is undefined.
/// However, callers must unconditionally zeroize the output buffer to
/// guard against leakage of cleartext data.
///
/// # Parameters
///
/// * `key`: Encryption key (must be 32 bytes).
/// * `iv`: Initialization Vector (must be 24 bytes).
/// * `aad`: Additional authenticated data (can be any length).
/// * `ciphertext`: Input buffer containing encrypted cipher text.
/// * `plaintext`: Output buffer containing decrypted plain text.
///
/// # Returns
///
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
/// library error code value.
pub fn decrypt(key: &[u8], iv: &[u8], aad: &[u8], ciphertext: &[u8],
plaintext: &mut [u8]) -> Result<(), i32> {
if key.len() != Self::KEYSIZE {
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
}
if iv.len() != Self::IV_SIZE {
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
}
let rc = unsafe {
sys::wc_XChaCha20Poly1305_Decrypt(
plaintext.as_mut_ptr(), plaintext.len(),
ciphertext.as_ptr(), ciphertext.len(),
aad.as_ptr(), aad.len(),
iv.as_ptr(), iv.len(),
key.as_ptr(), key.len())
};
if rc != 0 {
return Err(rc);
}
Ok(())
}

/// Encrypt an input message from `plaintext` using the XChaCha20 stream
/// cipher into the `ciphertext` output buffer performing Poly-1305
/// authentication on the cipher text.
/// The authentication tag is stored in the last 16 bytes of the
/// `ciphertext` buffer, so the `ciphertext` buffer must be large enough
/// for both the cipher text and authentication tag.
///
/// # Parameters
///
/// * `key`: Encryption key (must be 32 bytes).
/// * `iv`: Initialization Vector (must be 24 bytes).
/// * `aad`: Additional authenticated data (can be any length).
/// * `plaintext`: Input plain text to encrypt.
/// * `ciphertext`: Output buffer for encrypted cipher text.
///
/// # Returns
///
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
/// library error code value.
pub fn encrypt(key: &[u8], iv: &[u8], aad: &[u8], plaintext: &[u8],
ciphertext: &mut [u8]) -> Result<(), i32> {
if key.len() != Self::KEYSIZE {
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
}
if iv.len() != Self::IV_SIZE {
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
}
let rc = unsafe {
sys::wc_XChaCha20Poly1305_Encrypt(
ciphertext.as_mut_ptr(), ciphertext.len(),
plaintext.as_ptr(), plaintext.len(),
aad.as_ptr(), aad.len(),
iv.as_ptr(), iv.len(),
key.as_ptr(), key.len())
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
70 changes: 70 additions & 0 deletions wrapper/rust/wolfssl-wolfcrypt/tests/test_chacha20_poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,73 @@ fn test_chacha20_poly1305_2() {
assert_eq!(out_plaintext2, plaintext2);
assert_eq!(out_auth_tag_2, auth_tag_2);
}

#[test]
#[cfg(xchacha20_poly1305)]
fn test_xchacha20_poly1305() {
const PLAINTEXT: &[u8] = &[
0x4cu8, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, /* Ladies and Gentl */
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, /* emen of the clas */
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, /* s of '99: If I c */
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, /* ould offer you o */
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, /* nly one tip for */
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,
0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, /* the future, suns */
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, /* creen would be i */
0x74, 0x2e ]; /* t. */

let aad = [
0x50u8, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7
]; /* PQRS........ */

let key = [
0x80u8, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
];

let iv = [
0x40u8, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* @ABCDEFGHIJKLMNO */
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 /* PQRSTUVW */
];

let expected_ciphertext = [
0xbdu8, 0x6d, 0x17, 0x9d, 0x3e, 0x83, 0xd4, 0x3b,
0x95, 0x76, 0x57, 0x94, 0x93, 0xc0, 0xe9, 0x39,
0x57, 0x2a, 0x17, 0x00, 0x25, 0x2b, 0xfa, 0xcc,
0xbe, 0xd2, 0x90, 0x2c, 0x21, 0x39, 0x6c, 0xbb,
0x73, 0x1c, 0x7f, 0x1b, 0x0b, 0x4a, 0xa6, 0x44,
0x0b, 0xf3, 0xa8, 0x2f, 0x4e, 0xda, 0x7e, 0x39,
0xae, 0x64, 0xc6, 0x70, 0x8c, 0x54, 0xc2, 0x16,
0xcb, 0x96, 0xb7, 0x2e, 0x12, 0x13, 0xb4, 0x52,
0x2f, 0x8c, 0x9b, 0xa4, 0x0d, 0xb5, 0xd9, 0x45,
0xb1, 0x1b, 0x69, 0xb9, 0x82, 0xc1, 0xbb, 0x9e,
0x3f, 0x3f, 0xac, 0x2b, 0xc3, 0x69, 0x48, 0x8f,
0x76, 0xb2, 0x38, 0x35, 0x65, 0xd3, 0xff, 0xf9,
0x21, 0xf9, 0x66, 0x4c, 0x97, 0x63, 0x7d, 0xa9,
0x76, 0x88, 0x12, 0xf6, 0x15, 0xc6, 0x8b, 0x13,
0xb5, 0x2e
];

let expected_tag = [
0xc0u8, 0x87, 0x59, 0x24, 0xc1, 0xc7, 0x98, 0x79,
0x47, 0xde, 0xaf, 0xd8, 0x78, 0x0a, 0xcf, 0x49
];

let mut ciphertext_buffer = [0u8; PLAINTEXT.len() + XChaCha20Poly1305::AUTH_TAG_SIZE];
XChaCha20Poly1305::encrypt(&key, &iv, &aad, PLAINTEXT, &mut ciphertext_buffer).expect("Error with encrypt()");
assert_eq!(ciphertext_buffer[0..expected_ciphertext.len()], expected_ciphertext);
assert_eq!(ciphertext_buffer[expected_ciphertext.len()..], expected_tag);
let mut plaintext_buffer = [0u8; PLAINTEXT.len()];
XChaCha20Poly1305::decrypt(&key, &iv, &aad, &ciphertext_buffer, &mut plaintext_buffer).expect("Error with decrypt()");
assert_eq!(plaintext_buffer, PLAINTEXT);
}