/// Generate a random key of the right size for the given suite. /// /// # Errors /// /// If the ciphersuite or protocol version is not supported. pubfn generate_key(version: Version, cipher: Cipher) -> Res<SymKey> { // With generic_const_expr, this becomes: // import_key(version, &random::<{ key_size(version, cipher) }>())
import_key(
version,
&random::<MAX_KEY_SIZE>()[0..key_size(version, cipher)?],
)
}
/// Import a symmetric key for use with HKDF. /// /// # Errors /// /// Errors returned if the key buffer is an incompatible size or the NSS functions fail. pubfn import_key(version: Version, buf: &[u8]) -> Res<SymKey> { if version != TLS_VERSION_1_3 { return Err(Error::UnsupportedVersion);
} let slot = Slot::internal()?; let key_ptr = unsafe {
PK11_ImportDataKey(
*slot,
CK_MECHANISM_TYPE::from(CKM_HKDF_DERIVE),
PK11Origin::PK11_OriginUnwrap,
CK_ATTRIBUTE_TYPE::from(CKA_DERIVE),
SECItemBorrowed::wrap(buf)?.as_mut(),
null_mut(),
)
};
SymKey::from_ptr(key_ptr)
}
/// Extract a PRK from the given salt and IKM using the algorithm defined in RFC 5869. /// /// # Errors /// /// Errors returned if inputs are too large or the NSS functions fail. pubfn extract(
version: Version,
cipher: Cipher,
salt: Option<&SymKey>,
ikm: &SymKey,
) -> Res<SymKey> { letmut prk: *mut PK11SymKey = null_mut(); let salt_ptr: *mut PK11SymKey = salt.map_or(null_mut(), |s| **s); unsafe { SSL_HkdfExtract(version, cipher, salt_ptr, **ikm, &raw mut prk) }?;
SymKey::from_ptr(prk)
}
/// Expand a PRK using the HKDF-Expand-Label function defined in RFC 8446. /// /// # Errors /// /// Errors returned if inputs are too large or the NSS functions fail. pubfn expand_label(
version: Version,
cipher: Cipher,
prk: &SymKey,
handshake_hash: &[u8],
label: &str,
) -> Res<SymKey> { let l = label.as_bytes(); letmut secret: *mut PK11SymKey = null_mut();
// Note that this doesn't allow for passing null() for the handshake hash. // A zero-length slice produces an identical result. unsafe {
SSL_HkdfExpandLabel(
version,
cipher,
**prk,
handshake_hash.as_ptr(),
c_uint::try_from(handshake_hash.len())?,
l.as_ptr().cast(),
c_uint::try_from(l.len())?,
&raw mut secret,
)
}?;
SymKey::from_ptr(secret)
}
let slot = Slot::internal().map_err(|_| HkdfError::InternalError)?; let ikm_item = SECItemBorrowed::wrap(ikm).map_err(|_| HkdfError::InternalError)?; let ikm_item_ptr = std::ptr::from_ref(ikm_item.as_ref()).cast_mut();
let ptr = unsafe {
p11::PK11_ImportSymKey(
*slot,
CK_MECHANISM_TYPE::from(CKM_HKDF_KEY_GEN),
PK11Origin::PK11_OriginUnwrap,
CK_ATTRIBUTE_TYPE::from(CKA_SIGN),
ikm_item_ptr,
null_mut(),
)
}; let s = SymKey::from_ptr(ptr).map_err(|_| HkdfError::InternalError)?;
Ok(s)
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.