Skip to content

Commit 0162775

Browse files
committed
tests: Add basic ML-KEM Tests
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
1 parent eb3759d commit 0162775

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

cryptoki/tests/ml_kem.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright 2025 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
mod common;
4+
5+
use crate::common::{init_pins, USER_PIN};
6+
use cryptoki::context::Function;
7+
use cryptoki::mechanism::Mechanism;
8+
use cryptoki::object::{Attribute, AttributeType, KeyType, MlKemParameterSetType, ObjectClass};
9+
use cryptoki::session::UserType;
10+
use cryptoki::types::AuthPin;
11+
use serial_test::serial;
12+
13+
use testresult::TestResult;
14+
15+
#[test]
16+
#[serial]
17+
fn ml_kem() -> TestResult {
18+
let (pkcs11, slot) = init_pins();
19+
// PKCS#11 3.2 API is not supported by this token. Skip
20+
if !pkcs11.is_fn_supported(Function::EncapsulateKey) {
21+
/* return Ignore(); */
22+
print!("SKIP: The PKCS#11 module does not support encapsulation API");
23+
return Ok(());
24+
}
25+
26+
// open a session
27+
let session = pkcs11.open_rw_session(slot)?;
28+
29+
// log in the session
30+
session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;
31+
32+
let mechanism = Mechanism::MlKemKeyPairGen;
33+
34+
// pub key template
35+
let pub_key_template = vec![
36+
Attribute::Token(true),
37+
Attribute::MlKemParameterSet(MlKemParameterSetType::ML_KEM_768),
38+
Attribute::Encapsulate(true),
39+
];
40+
41+
// priv key template
42+
let priv_key_template = vec![Attribute::Token(true), Attribute::Decapsulate(true)];
43+
44+
// generate a key pair
45+
let (public, private) =
46+
session.generate_key_pair(&mechanism, &pub_key_template, &priv_key_template)?;
47+
48+
let secret_template = vec![
49+
Attribute::Token(true),
50+
Attribute::Class(ObjectClass::SECRET_KEY),
51+
Attribute::KeyType(KeyType::AES),
52+
Attribute::Sensitive(false),
53+
Attribute::Extractable(true),
54+
Attribute::Encrypt(true),
55+
Attribute::Decrypt(true),
56+
];
57+
58+
let mechanism = Mechanism::MlKem;
59+
60+
let (ciphertext, secret) = session.encapsulate_key(&mechanism, public, &secret_template)?;
61+
62+
let secret2 = session.decapsulate_key(&mechanism, private, &secret_template, &ciphertext)?;
63+
64+
// The secret and secret2 keys should be the same now. Try to extract them and compare
65+
let value_attribute = session
66+
.get_attributes(secret, &[AttributeType::Value])?
67+
.remove(0);
68+
let value = if let Attribute::Value(value) = value_attribute {
69+
value
70+
} else {
71+
panic!("Expected value attribute.");
72+
};
73+
let value_attribute2 = session
74+
.get_attributes(secret2, &[AttributeType::Value])?
75+
.remove(0);
76+
let value2 = if let Attribute::Value(value) = value_attribute2 {
77+
value
78+
} else {
79+
panic!("Expected value attribute.");
80+
};
81+
assert_eq!(value, value2);
82+
83+
// Test the generated keys can do some encryption/decryption operation
84+
let data = vec![
85+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
86+
0x0f,
87+
];
88+
89+
// Encrypt data with first key and decrypt with the other
90+
let ctext = session.encrypt(&Mechanism::AesEcb, secret, &data)?;
91+
let ptext = session.decrypt(&Mechanism::AesEcb, secret2, &ctext)?;
92+
assert_eq!(data, ptext);
93+
// and vice versa
94+
let ctext = session.encrypt(&Mechanism::AesEcb, secret2, &data)?;
95+
let ptext = session.decrypt(&Mechanism::AesEcb, secret, &ctext)?;
96+
assert_eq!(data, ptext);
97+
98+
// delete keys
99+
session.destroy_object(public)?;
100+
session.destroy_object(private)?;
101+
session.destroy_object(secret)?;
102+
session.destroy_object(secret2)?;
103+
104+
Ok(())
105+
}

0 commit comments

Comments
 (0)