summaryrefslogtreecommitdiff
path: root/ext/crypto/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/crypto/lib.rs')
-rw-r--r--ext/crypto/lib.rs28
1 files changed, 28 insertions, 0 deletions
diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs
index f2df7ba10..319f26c22 100644
--- a/ext/crypto/lib.rs
+++ b/ext/crypto/lib.rs
@@ -26,6 +26,7 @@ use rand::thread_rng;
use rand::Rng;
use rand::SeedableRng;
use ring::digest;
+use ring::hkdf;
use ring::hmac::Algorithm as HmacAlgorithm;
use ring::hmac::Key as HmacKey;
use ring::pbkdf2;
@@ -56,6 +57,7 @@ mod key;
use crate::key::Algorithm;
use crate::key::CryptoHash;
use crate::key::CryptoNamedCurve;
+use crate::key::HkdfOutput;
// Allowlist for RSA public exponents.
lazy_static! {
@@ -558,6 +560,7 @@ pub struct DeriveKeyArg {
hash: Option<CryptoHash>,
length: usize,
iterations: Option<u32>,
+ info: Option<ZeroCopyBuf>,
}
pub async fn op_crypto_derive_bits(
@@ -589,6 +592,31 @@ pub async fn op_crypto_derive_bits(
pbkdf2::derive(algorithm, iterations, salt, &secret, &mut out);
Ok(out.into())
}
+ Algorithm::Hkdf => {
+ let algorithm = match args.hash.ok_or_else(not_supported)? {
+ CryptoHash::Sha1 => hkdf::HKDF_SHA1_FOR_LEGACY_USE_ONLY,
+ CryptoHash::Sha256 => hkdf::HKDF_SHA256,
+ CryptoHash::Sha384 => hkdf::HKDF_SHA384,
+ CryptoHash::Sha512 => hkdf::HKDF_SHA512,
+ };
+
+ let info = args
+ .info
+ .ok_or_else(|| type_error("Missing argument info".to_string()))?;
+ // IKM
+ let secret = args.key.data;
+ // L
+ let length = args.length / 8;
+
+ let salt = hkdf::Salt::new(algorithm, salt);
+ let prk = salt.extract(&secret);
+ let info = &[&*info];
+ let okm = prk.expand(info, HkdfOutput(length))?;
+ let mut r = vec![0u8; length];
+ okm.fill(&mut r)?;
+
+ Ok(r.into())
+ }
_ => Err(type_error("Unsupported algorithm".to_string())),
}
}