From 266faf594ab95659bdfab0c8eb47a54db5628946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20J=C3=B6rg=20Schmidt?= Date: Thu, 2 Jan 2025 14:18:51 +0100 Subject: [PATCH] extend nss bindings with methods for key management To manage AES-256 GCM keys with NSS in the way that is currently implemented on the desktop, we need extended functionality of the Rust bindings to NSS. Specifically, these are functions for key generation with persistence, for listing persisted keys, and for wrapping and unwrapping to get at the key material of stored keys. --- CHANGELOG.md | 3 ++ .../nss/nss_sys/src/bindings/blapit.rs | 1 + .../nss/nss_sys/src/bindings/pk11pub.rs | 52 ++++++++++++++++++- .../nss/nss_sys/src/bindings/pkcs11t.rs | 4 ++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52793623ac..083f8e5d4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ [Full Changelog](In progress) +### `rc_crypto` +- New low level bindings for functions for key generation with persistence, for listing persisted keys, and for wrapping and unwrapping to get at the key material of stored keys. + ## 🦊 What's Changed 🦊 ### Glean diff --git a/components/support/rc_crypto/nss/nss_sys/src/bindings/blapit.rs b/components/support/rc_crypto/nss/nss_sys/src/bindings/blapit.rs index 4eb4243b66..603971423c 100644 --- a/components/support/rc_crypto/nss/nss_sys/src/bindings/blapit.rs +++ b/components/support/rc_crypto/nss/nss_sys/src/bindings/blapit.rs @@ -7,3 +7,4 @@ pub const SHA256_LENGTH: u32 = 32; pub const SHA384_LENGTH: u32 = 48; pub const HASH_LENGTH_MAX: u32 = 64; pub const AES_BLOCK_SIZE: u32 = 16; +pub const AES_256_KEY_LENGTH: u32 = 32; diff --git a/components/support/rc_crypto/nss/nss_sys/src/bindings/pk11pub.rs b/components/support/rc_crypto/nss/nss_sys/src/bindings/pk11pub.rs index 3c10dc09bc..48ef60dcc9 100644 --- a/components/support/rc_crypto/nss/nss_sys/src/bindings/pk11pub.rs +++ b/components/support/rc_crypto/nss/nss_sys/src/bindings/pk11pub.rs @@ -3,13 +3,26 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ pub use crate::*; -use std::os::raw::{c_int, c_uchar, c_uint, c_void}; +use std::os::raw::{c_char, c_int, c_uchar, c_uint, c_void}; extern "C" { pub fn PK11_FreeSlot(slot: *mut PK11SlotInfo); pub fn PK11_GetInternalSlot() -> *mut PK11SlotInfo; + pub fn PK11_GetInternalKeySlot() -> *mut PK11SlotInfo; pub fn PK11_GenerateRandom(data: *mut c_uchar, len: c_int) -> SECStatus; pub fn PK11_FreeSymKey(key: *mut PK11SymKey); + pub fn PK11_InitPin( + slot: *mut PK11SlotInfo, + ssopw: *const c_char, + pk11_userpwd: *const c_char, + ) -> SECStatus; + pub fn PK11_KeyGen( + slot: *mut PK11SlotInfo, + type_: CK_MECHANISM_TYPE, + param: *mut SECItem, + keySize: c_int, + wincx: *mut c_void, + ) -> *mut PK11SymKey; pub fn PK11_ImportSymKey( slot: *mut PK11SlotInfo, type_: CK_MECHANISM_TYPE, @@ -18,6 +31,16 @@ extern "C" { key: *mut SECItem, wincx: *mut c_void, ) -> *mut PK11SymKey; + pub fn PK11_ImportSymKeyWithFlags( + slot: *mut PK11SlotInfo, + type_: CK_MECHANISM_TYPE, + origin: u32, /* PK11Origin */ + operation: CK_ATTRIBUTE_TYPE, + key: *mut SECItem, + flags: CK_FLAGS, + isPerm: PRBool, + wincx: *mut c_void, + ) -> *mut PK11SymKey; pub fn PK11_Derive( baseKey: *mut PK11SymKey, mechanism: CK_MECHANISM_TYPE, @@ -40,6 +63,22 @@ extern "C" { sharedData: *mut SECItem, wincx: *mut c_void, ) -> *mut PK11SymKey; + pub fn PK11_WrapSymKey( + type_: CK_MECHANISM_TYPE, + param: *mut SECItem, + wrappingKey: *mut PK11SymKey, + symKey: *mut PK11SymKey, + wrappedKey: *mut SECItem, + ) -> SECStatus; + pub fn PK11_UnwrapSymKey( + wrappingKey: *mut PK11SymKey, + wrapType: CK_MECHANISM_TYPE, + param: *mut SECItem, + wrappedKey: *mut SECItem, + target: CK_MECHANISM_TYPE, + operation: CK_ATTRIBUTE_TYPE, + keySize: c_int, + ) -> *mut PK11SymKey; pub fn PK11_ExtractKeyValue(symKey: *mut PK11SymKey) -> SECStatus; pub fn PK11_GetKeyData(symKey: *mut PK11SymKey) -> *mut SECItem; pub fn PK11_GenerateKeyPair( @@ -56,6 +95,11 @@ extern "C" { keyID: *mut SECItem, wincx: *mut c_void, ) -> *mut SECKEYPrivateKey; + pub fn PK11_ListFixedKeysInSlot( + slot: *mut PK11SlotInfo, + nickname: *mut c_char, + wincx: *mut c_void, + ) -> *mut PK11SymKey; pub fn PK11_Decrypt( symkey: *mut PK11SymKey, mechanism: CK_MECHANISM_TYPE, @@ -127,7 +171,6 @@ extern "C" { iteration: c_int, salt: *mut SECItem, ) -> *mut SECAlgorithmID; - pub fn PK11_PBEKeyGen( slot: *mut PK11SlotInfo, algid: *mut SECAlgorithmID, @@ -135,4 +178,9 @@ extern "C" { faulty3DES: PRBool, wincx: *mut c_void, ) -> *mut PK11SymKey; + pub fn SECITEM_AllocItem( + arena: *mut PLArenaPool, + item: *mut SECItem, + len: c_uint, + ) -> *mut SECItem; } diff --git a/components/support/rc_crypto/nss/nss_sys/src/bindings/pkcs11t.rs b/components/support/rc_crypto/nss/nss_sys/src/bindings/pkcs11t.rs index 01cea5e1f9..8a3f7d47c0 100644 --- a/components/support/rc_crypto/nss/nss_sys/src/bindings/pkcs11t.rs +++ b/components/support/rc_crypto/nss/nss_sys/src/bindings/pkcs11t.rs @@ -15,6 +15,7 @@ pub type CK_OBJECT_HANDLE = CK_ULONG; pub type CK_OBJECT_CLASS = CK_ULONG; pub type CK_KEY_TYPE = CK_ULONG; pub type CK_ATTRIBUTE_TYPE = CK_ULONG; +pub type CK_FLAGS = CK_ULONG; #[repr(C)] #[derive(Clone, Copy)] pub struct CK_ATTRIBUTE { @@ -35,6 +36,7 @@ pub const CKA_KEY_TYPE: u32 = 256; pub const CKA_ID: u32 = 258; pub const CKA_SENSITIVE: u32 = 259; pub const CKA_ENCRYPT: u32 = 260; +pub const CKA_DECRYPT: u32 = 261; pub const CKA_WRAP: u32 = 262; pub const CKA_SIGN: u32 = 264; pub const CKA_EC_PARAMS: u32 = 384; @@ -48,4 +50,6 @@ pub const CKM_EC_KEY_PAIR_GEN: u32 = 4160; pub const CKM_ECDH1_DERIVE: u32 = 4176; pub const CKM_AES_CBC_PAD: u32 = 4229; pub const CKM_AES_GCM: u32 = 4231; +pub const CKM_AES_KEY_GEN: u64 = 0x00001080; +pub const CKM_AES_KEY_WRAP_KWP: u64 = 0x0000210B; pub const CKD_NULL: u32 = 1;