@@ -89,3 +89,105 @@ impl<'a> GcmParams<'a> {
8989 self . inner . ulTagBits . into ( )
9090 }
9191}
92+
93+ /// The GCM generator function for the Initialization Vector
94+ #[ derive( Debug , Clone , Copy ) ]
95+ pub enum GeneratorFunction {
96+ /// `CKG_NO_GENERATE` no IV generation is done.
97+ NoGenerate ,
98+ /// `CKG_GENERATE` the non-fixed part of IV is generated internally
99+ Generate ,
100+ /// `CKG_GENERATE_COUNTER` the non-fixed part of IV is generated internally by incrementing
101+ /// counter. Initially zero.
102+ GenerateCounter ,
103+ /// `CKG_GENERATE_RANDOM` the non-fixed part of IV is generated internally by PRNG
104+ GenerateRandom ,
105+ /// `CKG_GENERATE_COUNTER_XOR` the non-fixed part of IV xored with incrementing counter.
106+ GenerateCounterXor ,
107+ }
108+
109+ /// Parameters for message based AES-GCM operations.
110+ #[ derive( Debug , Copy , Clone ) ]
111+ #[ repr( transparent) ]
112+ pub struct GcmMessageParams < ' a > {
113+ inner : CK_GCM_MESSAGE_PARAMS ,
114+ _marker : PhantomData < & ' a mut [ u8 ] > ,
115+ }
116+
117+ impl < ' a > GcmMessageParams < ' a > {
118+ /// Construct GCM parameters for message based operations
119+ ///
120+ /// # Arguments
121+ ///
122+ /// `iv` - The initialization vector. This must be non-empty. In PKCS#11
123+ /// 3.0, the maximum length of the IV is 256 bytes. A 12-byte IV may be
124+ /// processed more efficiently than other lengths.
125+ ///
126+ /// `iv_fixed_bits` - number of bits of the original IV to preserve when
127+ /// generating an new IV. These bits are counted from the Most significant
128+ /// bits (to the right).
129+ ///
130+ /// `iv_generator` - Function used to generate a new IV. Each IV must be
131+ /// unique for a given session.
132+ ///
133+ /// `tag` - The buffer to store the tag. Either to be passed in or returned if generated by
134+ /// token.
135+ ///
136+ /// # Errors
137+ /// This function returns an error if the length of `iv` does not
138+ /// fit into an [Ulong].
139+ pub fn new (
140+ iv : & ' a mut [ u8 ] ,
141+ iv_fixed_bits : Ulong ,
142+ iv_generator : GeneratorFunction ,
143+ tag : & ' a mut [ u8 ] ,
144+ ) -> Result < Self , Error > {
145+ let tag_bits = tag. len ( ) * 8 ;
146+ Ok ( GcmMessageParams {
147+ inner : CK_GCM_MESSAGE_PARAMS {
148+ pIv : iv. as_mut_ptr ( ) ,
149+ ulIvLen : iv. len ( ) . try_into ( ) ?,
150+ ulIvFixedBits : iv_fixed_bits. into ( ) ,
151+ ivGenerator : match iv_generator {
152+ GeneratorFunction :: NoGenerate => CKG_NO_GENERATE ,
153+ GeneratorFunction :: Generate => CKG_GENERATE ,
154+ GeneratorFunction :: GenerateCounter => CKG_GENERATE_COUNTER ,
155+ GeneratorFunction :: GenerateRandom => CKG_GENERATE_RANDOM ,
156+ GeneratorFunction :: GenerateCounterXor => CKG_GENERATE_COUNTER_XOR ,
157+ } ,
158+ pTag : tag. as_mut_ptr ( ) ,
159+ ulTagBits : tag_bits. try_into ( ) ?,
160+ } ,
161+ _marker : PhantomData ,
162+ } )
163+ }
164+
165+ /// The initialization vector.
166+ pub fn iv ( & mut self ) -> & mut [ u8 ] {
167+ // SAFETY: In the constructor, the IV always comes from a &'a mut [u8]
168+ unsafe { slice:: from_raw_parts_mut ( self . inner . pIv , self . inner . ulIvLen as _ ) }
169+ }
170+
171+ /// The length, in bits, of fixed part of the IV.
172+ pub fn iv_fixed_bits ( & self ) -> Ulong {
173+ self . inner . ulIvFixedBits . into ( )
174+ }
175+
176+ /// The IV generator.
177+ pub fn iv_generator ( & self ) -> GeneratorFunction {
178+ match self . inner . ivGenerator {
179+ CKG_NO_GENERATE => GeneratorFunction :: NoGenerate ,
180+ CKG_GENERATE => GeneratorFunction :: Generate ,
181+ CKG_GENERATE_COUNTER => GeneratorFunction :: GenerateCounter ,
182+ CKG_GENERATE_RANDOM => GeneratorFunction :: GenerateRandom ,
183+ CKG_GENERATE_COUNTER_XOR => GeneratorFunction :: GenerateCounterXor ,
184+ _ => unreachable ! ( ) ,
185+ }
186+ }
187+
188+ /// The authentication tag.
189+ pub fn tag ( & self ) -> & ' a [ u8 ] {
190+ // SAFETY: In the constructor, the tag always comes from a &'a [u8]
191+ unsafe { slice:: from_raw_parts ( self . inner . pTag , ( self . inner . ulTagBits / 8 ) as _ ) }
192+ }
193+ }
0 commit comments