usesuper::CryptoError; use openssl::bn::BigNumContext; use openssl::derive::Deriver; use openssl::ec::{EcGroup, EcKey, PointConversionForm}; use openssl::error::ErrorStack; use openssl::hash::{hash, MessageDigest}; use openssl::nid::Nid; use openssl::pkey::{PKey, Private, Public}; use openssl::rand::rand_bytes; use openssl::sign::Signer; use openssl::symm::{Cipher, Crypter, Mode}; use std::os::raw::c_int;
/// ECDH using OpenSSL types. Computes the x coordinate of scalar multiplication of `peer_public` /// by `client_private`. fn ecdh_openssl_raw(client_private: EcKey<Private>, peer_public: EcKey<Public>) -> Result<Vec<u8>> { let client_pkey = PKey::from_ec_key(client_private)?; let peer_pkey = PKey::from_ec_key(peer_public)?; letmut deriver = Deriver::new(&client_pkey)?;
deriver.set_peer(&peer_pkey)?; let shared_point = deriver.derive_to_vec()?;
Ok(shared_point)
}
/// Ephemeral ECDH over P256. Takes a DER SubjectPublicKeyInfo that encodes a public key. Generates /// an ephemeral P256 key pair. Returns /// 1) the x coordinate of the shared point, and /// 2) the uncompressed SEC 1 encoding of the ephemeral public key. pubfn ecdhe_p256_raw(peer_spki: &[u8]) -> Result<(Vec<u8>, Vec<u8>)> { let peer_public = EcKey::public_key_from_der(peer_spki)?;
// Hard-coding the P256 group here is easier than extracting a group name from peer_public and // comparing it with P256. We'll fail in key derivation if peer_public is on the wrong curve. let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1)?;
letmut bn_ctx = BigNumContext::new()?; let client_private = EcKey::generate(&group)?; let client_public_sec1 = client_private.public_key().to_bytes(
&group,
PointConversionForm::UNCOMPRESSED,
&mut bn_ctx,
)?;
let shared_point = ecdh_openssl_raw(client_private, peer_public)?;
Ok((shared_point, client_public_sec1))
}
/// AES-256-CBC encryption for data that is a multiple of the AES block size (16 bytes) in length. /// Uses the zero IV if `iv` is None. pubfn encrypt_aes_256_cbc_no_pad(key: &[u8], iv: Option<&[u8]>, data: &[u8]) -> Result<Vec<u8>> { let iv = iv.unwrap_or(&[0u8; AES_BLOCK_SIZE]);
let in_len = data.len(); if in_len % AES_BLOCK_SIZE != 0 { return Err(CryptoError::LibraryFailure);
}
// OpenSSL would panic if we didn't allocate an extra block here. letmut out = vec![0; in_len + AES_BLOCK_SIZE]; letmut out_len = 0;
out_len += encrypter.update(data, out.as_mut_slice())?;
out_len += encrypter.finalize(out.as_mut_slice())?;
debug_assert_eq!(in_len, out_len);
out.truncate(out_len);
Ok(out)
}
/// AES-256-CBC decryption for data that is a multiple of the AES block size (16 bytes) in length. /// Uses the zero IV if `iv` is None. pubfn decrypt_aes_256_cbc_no_pad(key: &[u8], iv: Option<&[u8]>, data: &[u8]) -> Result<Vec<u8>> { let iv = iv.unwrap_or(&[0u8; AES_BLOCK_SIZE]);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.