1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
// Copyright 2023 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
//! AEAD block cipher mechanism types
use crate::types::Ulong;
use cryptoki_sys::*;
use std::convert::TryInto;
use std::marker::PhantomData;
use std::slice;
/// Parameters for AES-GCM.
#[derive(Debug, Clone, Copy)]
#[repr(transparent)]
pub struct GcmParams<'a> {
inner: CK_GCM_PARAMS,
_marker: PhantomData<&'a [u8]>,
}
impl<'a> GcmParams<'a> {
/// Construct GCM parameters.
///
/// # Arguments
///
/// `iv` - The initialization vector. This must be non-empty. In PKCS#11
/// 2.40, the maximum length of the IV is 256 bytes. A 12-byte IV may be
/// processed more efficiently than other lengths.
///
/// `aad` - The additional authenticated data. This data is authenticated
/// but not encrypted. This may be between 0 and 2^32-1 bytes.
///
/// `tag_bits` - The length, in **bits**, of the authentication tag. Must
/// be between 0 and 128. The tag is appended to the end of the
/// ciphertext.
///
/// # Panics
///
/// This function panics if the length of `iv` or `aad` does not
/// fit into an [Ulong].
pub fn new(iv: &'a [u8], aad: &'a [u8], tag_bits: Ulong) -> Self {
// The ulIvBits parameter seems to be missing from the 2.40 spec,
// although it is included in the header file. In [1], OASIS clarified
// that the header file is normative. In 3.0, they added the parameter
// to the spec, but it seems to be unused:
//
// > Do not use ulIvBits to specify the length of the initialization
// > vector, but ulIvLen instead.
//
// Further, in v3.0, the IV is permitted to be up to 2^32-1 bytes,
// which would cause ulIvBits to overflow on platforms where
// sizeof(CK_ULONG) = 4.
//
// In light of all this, we include ulIvBits in the struct, but always
// set it to zero.
//
// [1]: https://www.oasis-open.org/committees/document.php?document_id=58032&wg_abbrev=pkcs11
GcmParams {
inner: CK_GCM_PARAMS {
pIv: iv.as_ptr() as *mut _,
ulIvLen: iv
.len()
.try_into()
.expect("iv length does not fit in CK_ULONG"),
ulIvBits: 0,
pAAD: aad.as_ptr() as *mut _,
ulAADLen: aad
.len()
.try_into()
.expect("aad length does not fit in CK_ULONG"),
ulTagBits: tag_bits.into(),
},
_marker: PhantomData,
}
}
/// The initialization vector.
pub fn iv(&self) -> &'a [u8] {
// SAFETY: In the constructor, the IV always comes from a &'a [u8]
unsafe { slice::from_raw_parts(self.inner.pIv, self.inner.ulIvLen as _) }
}
/// The additional authenticated data.
pub fn aad(&self) -> &'a [u8] {
// SAEFTY: In the constructor, the AAD always comes from a &'a [u8]
unsafe { slice::from_raw_parts(self.inner.pAAD, self.inner.ulAADLen as _) }
}
/// The length, in bits, of the authentication tag.
pub fn tag_bits(&self) -> Ulong {
self.inner.ulTagBits.into()
}
}