summaryrefslogtreecommitdiff
path: root/ext/crypto/lib.rs
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2021-10-08 20:59:36 +0530
committerGitHub <noreply@github.com>2021-10-08 17:29:36 +0200
commita5d3c8b06cba652b902fdfaa3f13ed40483e90c0 (patch)
tree967413a9cdab742cbc7a500006859ac938b79d53 /ext/crypto/lib.rs
parentc49a057599d68b27c88cc123a9fcd6703b49310c (diff)
feat(ext/crypto): implement deriveBits for ECDH (p256) (#11873)
Diffstat (limited to 'ext/crypto/lib.rs')
-rw-r--r--ext/crypto/lib.rs39
1 files changed, 37 insertions, 2 deletions
diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs
index 948ef53a1..6376aedbb 100644
--- a/ext/crypto/lib.rs
+++ b/ext/crypto/lib.rs
@@ -43,6 +43,7 @@ use rsa::pkcs1::der::Encodable;
use rsa::pkcs1::FromRsaPrivateKey;
use rsa::pkcs1::ToRsaPrivateKey;
use rsa::pkcs8::der::asn1;
+use rsa::pkcs8::FromPrivateKey;
use rsa::BigUint;
use rsa::PublicKey;
use rsa::RsaPrivateKey;
@@ -792,18 +793,23 @@ pub struct DeriveKeyArg {
hash: Option<CryptoHash>,
length: usize,
iterations: Option<u32>,
+ // ECDH
+ public_key: Option<KeyData>,
+ named_curve: Option<CryptoNamedCurve>,
+ // HKDF
info: Option<ZeroCopyBuf>,
}
pub async fn op_crypto_derive_bits(
_state: Rc<RefCell<OpState>>,
args: DeriveKeyArg,
- zero_copy: ZeroCopyBuf,
+ zero_copy: Option<ZeroCopyBuf>,
) -> Result<ZeroCopyBuf, AnyError> {
- let salt = &*zero_copy;
let algorithm = args.algorithm;
match algorithm {
Algorithm::Pbkdf2 => {
+ let zero_copy = zero_copy.ok_or_else(not_supported)?;
+ let salt = &*zero_copy;
// The caller must validate these cases.
assert!(args.length > 0);
assert!(args.length % 8 == 0);
@@ -823,7 +829,36 @@ pub async fn op_crypto_derive_bits(
pbkdf2::derive(algorithm, iterations, salt, &secret, &mut out);
Ok(out.into())
}
+ Algorithm::Ecdh => {
+ let named_curve = args
+ .named_curve
+ .ok_or_else(|| type_error("Missing argument namedCurve".to_string()))?;
+
+ let public_key = args
+ .public_key
+ .ok_or_else(|| type_error("Missing argument publicKey".to_string()))?;
+
+ match named_curve {
+ CryptoNamedCurve::P256 => {
+ let secret_key = p256::SecretKey::from_pkcs8_der(&args.key.data)?;
+ let public_key =
+ p256::SecretKey::from_pkcs8_der(&public_key.data)?.public_key();
+
+ let shared_secret = p256::elliptic_curve::ecdh::diffie_hellman(
+ secret_key.to_secret_scalar(),
+ public_key.as_affine(),
+ );
+
+ Ok(shared_secret.as_bytes().to_vec().into())
+ }
+ // TODO(@littledivy): support for P384
+ // https://github.com/RustCrypto/elliptic-curves/issues/240
+ _ => Err(type_error("Unsupported namedCurve".to_string())),
+ }
+ }
Algorithm::Hkdf => {
+ let zero_copy = zero_copy.ok_or_else(not_supported)?;
+ let salt = &*zero_copy;
let algorithm = match args.hash.ok_or_else(not_supported)? {
CryptoHash::Sha1 => hkdf::HKDF_SHA1_FOR_LEGACY_USE_ONLY,
CryptoHash::Sha256 => hkdf::HKDF_SHA256,