summaryrefslogtreecommitdiff
path: root/ext/node/crypto/mod.rs
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2023-04-06 22:26:56 +0530
committerGitHub <noreply@github.com>2023-04-06 16:56:56 +0000
commitdf72420d723affb780c0c388b7d704985288f801 (patch)
tree6e6da7d1a93930c6742c98c838eeae55678e144e /ext/node/crypto/mod.rs
parent2d0a9ffbccf9d8a4773eb6efa48ddc6978af6455 (diff)
fix(ext/node): implement hkdf-expand (#18612)
Towards https://github.com/denoland/deno/issues/18455
Diffstat (limited to 'ext/node/crypto/mod.rs')
-rw-r--r--ext/node/crypto/mod.rs58
1 files changed, 58 insertions, 0 deletions
diff --git a/ext/node/crypto/mod.rs b/ext/node/crypto/mod.rs
index 499e99fea..adacdf6d6 100644
--- a/ext/node/crypto/mod.rs
+++ b/ext/node/crypto/mod.rs
@@ -7,6 +7,7 @@ use deno_core::OpState;
use deno_core::ResourceId;
use deno_core::StringOrBuffer;
use deno_core::ZeroCopyBuf;
+use hkdf::Hkdf;
use num_bigint::BigInt;
use rand::Rng;
use std::future::Future;
@@ -419,3 +420,60 @@ pub async fn op_node_generate_secret_async(len: i32) -> ZeroCopyBuf {
.await
.unwrap()
}
+
+fn hkdf_sync(
+ hash: &str,
+ ikm: &[u8],
+ salt: &[u8],
+ info: &[u8],
+ okm: &mut [u8],
+) -> Result<(), AnyError> {
+ macro_rules! hkdf {
+ ($hash:ty) => {{
+ let hk = Hkdf::<$hash>::new(Some(salt), ikm);
+ hk.expand(info, okm)
+ .map_err(|_| type_error("HKDF-Expand failed"))?;
+ }};
+ }
+
+ match hash {
+ "md4" => hkdf!(md4::Md4),
+ "md5" => hkdf!(md5::Md5),
+ "ripemd160" => hkdf!(ripemd::Ripemd160),
+ "sha1" => hkdf!(sha1::Sha1),
+ "sha224" => hkdf!(sha2::Sha224),
+ "sha256" => hkdf!(sha2::Sha256),
+ "sha384" => hkdf!(sha2::Sha384),
+ "sha512" => hkdf!(sha2::Sha512),
+ _ => return Err(type_error("Unknown digest")),
+ }
+
+ Ok(())
+}
+
+#[op]
+pub fn op_node_hkdf(
+ hash: &str,
+ ikm: &[u8],
+ salt: &[u8],
+ info: &[u8],
+ okm: &mut [u8],
+) -> Result<(), AnyError> {
+ hkdf_sync(hash, ikm, salt, info, okm)
+}
+
+#[op]
+pub async fn op_node_hkdf_async(
+ hash: String,
+ ikm: ZeroCopyBuf,
+ salt: ZeroCopyBuf,
+ info: ZeroCopyBuf,
+ okm_len: usize,
+) -> Result<ZeroCopyBuf, AnyError> {
+ tokio::task::spawn_blocking(move || {
+ let mut okm = vec![0u8; okm_len];
+ hkdf_sync(&hash, &ikm, &salt, &info, &mut okm)?;
+ Ok(okm.into())
+ })
+ .await?
+}