Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: NASL builtin functions for smb #1771

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions rust/src/nasl/builtin/cryptographic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod hash;
pub mod hmac;
pub mod rc4;
pub mod rsa;
pub mod smb;

#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -123,6 +124,7 @@ impl IntoFunctionSet for Cryptographic {
set.add_set(des::Des);
set.add_set(rsa::Rsa);
set.add_set(bf_cbc::BfCbc);
set.add_set(smb::Smb);
set
}
}
88 changes: 88 additions & 0 deletions rust/src/nasl/builtin/cryptographic/smb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-FileCopyrightText: 2024 Greenbone AG
//

// SPDX-License-Identifier: GPL-2.0-or-later
use crate::function_set;
use crate::nasl::FunctionErrorKind;
use crate::nasl::NaslValue;
use aes::Aes128;
use aes_gcm::aead::{Aead, KeyInit};
use aes_gcm::{Aes128Gcm, Nonce};
use cmac::Cmac;
use cmac::Mac;
use digest::InvalidLength;
use hmac::Hmac;
use nasl_function_proc_macro::nasl_function;
use sha2::Sha256;

#[nasl_function(named(key, buf))]
fn smb_cmac_aes_signature(key: &str, buf: &str) -> Result<NaslValue, FunctionErrorKind> {
let key_bytes = key.as_bytes();
let buf_bytes = buf.as_bytes();
let mut cmac_obj = <Cmac<Aes128> as KeyInit>::new_from_slice(key_bytes)
.map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))?;
Mac::update(&mut cmac_obj, buf_bytes);
let finish = cmac::Mac::finalize(cmac_obj).into_bytes();
Ok(finish.to_vec().into())
}

#[nasl_function(named(key, buf, iv))]
fn smb_gmac_aes_signature(key: &str, buf: &str, iv: &str) -> Result<NaslValue, FunctionErrorKind> {
let key_bytes = key.as_bytes();
let buf_bytes = buf.as_bytes();
let iv_bytes = iv.as_bytes();
let gmac = Aes128Gcm::new_from_slice(key_bytes).unwrap();
let nonce = Nonce::from_slice(iv_bytes);
let auth = gmac.encrypt(nonce, buf_bytes.as_ref()).unwrap();
Ok(auth.into())
}
#[nasl_function(named(key, label, ctx, lvalue))]
fn smb3kdf(
key: &str,
label: &str,
ctx: &str,
lvalue: usize,
) -> Result<NaslValue, FunctionErrorKind> {
let key_bytes = key.as_bytes();
let label_bytes = label.as_bytes();
let ctx_bytes = ctx.as_bytes();
let mut mac_obj = match <Hmac<Sha256> as KeyInit>::new_from_slice(key_bytes) {
Ok(x) => x,
Err(InvalidLength) => {
return Err(FunctionErrorKind::wrong_unnamed_argument(
"valid size key",
"invalid size key",
))
}
};
if lvalue != 128 && lvalue != 256 {
return Err(FunctionErrorKind::wrong_argument(
"valid size key",
format!("{:?}", "128 or 256").as_str(),
lvalue.to_string().as_str(),
));
}
let buflen = 4 + label_bytes.len() + 1 + ctx_bytes.len();
let mut buf = Vec::with_capacity(buflen);

buf.extend_from_slice(&1u32.to_be_bytes());
buf.extend_from_slice(label_bytes);
buf.push(0);
buf.extend_from_slice(ctx_bytes);
buf.extend_from_slice(&lvalue.to_be_bytes());
mac_obj.update(&buf);
let result = mac_obj.finalize().into_bytes();
let resultlen = (lvalue / 8) as usize;
Ok(result[..resultlen].into())
}

pub struct Smb;
function_set! {
Smb,
sync_stateless,
(
(smb_gmac_aes_signature, "smb_gmac_aes_signature"),
(smb_cmac_aes_signature, "smb_cmac_aes_signature"),
(smb3kdf, "smb3kdf"),
)
}
1 change: 1 addition & 0 deletions rust/src/nasl/builtin/cryptographic/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ mod helper;
mod hmac;
mod rc4;
mod rsa;
mod smb;
47 changes: 47 additions & 0 deletions rust/src/nasl/builtin/cryptographic/tests/smb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: 2024 Greenbone AG
//
// SPDX-License-Identifier: GPL-2.0-or-later

#[cfg(test)]
mod tests {

use crate::nasl::builtin::cryptographic::tests::helper::decode_hex;
use crate::nasl::test_prelude::*;
use crate::nasl::test_utils::TestBuilder;

#[test]
fn smb_cmac_aes_signature() {
let mut t = TestBuilder::default();
t.run(r#"key = "1274637383948293";"#);
t.run(r#"buf = "1274637383948293";"#);
t.ok(
r#"smb_cmac_aes_signature(key:key,buf:buf);"#,
NaslValue::Data(decode_hex("73C1B26E84FFC51037E057734B8AC8E2").unwrap()),
);
}
#[test]
fn smb_gmac_aes_signature() {
let mut t = TestBuilder::default();
t.run(r#"key = "1274637383948293";"#);
t.run(r#"buf = "1274637383948293";"#);
t.run(r#"iv = "127463738394";"#);
t.ok(
r#"smb_gmac_aes_signature(key:key,buf:buf,iv:iv);"#,
NaslValue::Data(decode_hex("73C1B26E84FFC51037E057734B8AC8E2").unwrap()),
);
}
#[test]
fn smb3kdf() {
let mut t: TestBuilder<crate::nasl::NoOpLoader, crate::storage::DefaultDispatcher> =
TestBuilder::default();
t.run(r#"key = "jfehfiuhf497hfiuhwf497g74gf97wh4u97hg";"#);
t.run(r#"label = "1274637383948293";"#);
t.run(r#"ctx = "28374928";"#);
t.run(r#"lvalue = 128;"#);
t.run(r#"display(smb3kdf(key:key,label:label,ctx:ctx,lvalue:lvalue));"#);
t.ok(
r#"smb3kdf(key:key,label:label,ctx:ctx,lvalue:lvalue);"#,
NaslValue::Data(decode_hex("73C1B26E84FFC51037E057734B8AC8E2").unwrap()),
);
}
}
Loading