@@ -269,6 +269,114 @@ pub fn pkcs12_pbkdf_ex(password: &[u8], salt: &[u8], iterations: i32, typ: i32,
269269 Ok ( ( ) )
270270}
271271
272+ /// Implement the scrypt password-based key derivation function as defined
273+ /// in RFC 7914.
274+ ///
275+ /// # Parameters
276+ ///
277+ /// * `password`: Password to use for key derivation.
278+ /// * `salt`: Salt value to use for key derivation.
279+ /// * `cost`: log base 2 of the iteration count (`N = 1 << cost`). Must
280+ /// satisfy `1 <= cost < 128 * block_size / 8`.
281+ /// * `block_size`: Number of 128-byte octets in a working block (the `r`
282+ /// parameter from RFC 7914). Must be in `1..=8`.
283+ /// * `parallel`: Number of parallel mix operations to perform (the `p`
284+ /// parameter from RFC 7914). This implementation does not use threads.
285+ /// * `out`: Output buffer in which to store the derived key.
286+ ///
287+ /// # Returns
288+ ///
289+ /// Returns either Ok(()) on success or Err(e) containing the wolfSSL
290+ /// library error code value.
291+ ///
292+ /// # Example
293+ ///
294+ /// ```rust
295+ /// #[cfg(kdf_scrypt)]
296+ /// {
297+ /// use wolfssl_wolfcrypt::kdf::scrypt;
298+ /// let password = b"password";
299+ /// let salt = b"NaCl";
300+ /// let expected_key = [
301+ /// 0xfdu8, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00,
302+ /// 0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe,
303+ /// 0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30,
304+ /// 0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62,
305+ /// 0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88,
306+ /// 0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda,
307+ /// 0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d,
308+ /// 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40
309+ /// ];
310+ /// let mut keyout = [0u8; 64];
311+ /// scrypt(password, salt, 10, 8, 16, &mut keyout).expect("Error with scrypt()");
312+ /// assert_eq!(keyout, expected_key);
313+ /// }
314+ /// ```
315+ #[ cfg( kdf_scrypt) ]
316+ pub fn scrypt ( password : & [ u8 ] , salt : & [ u8 ] , cost : i32 , block_size : i32 ,
317+ parallel : i32 , out : & mut [ u8 ] ) -> Result < ( ) , i32 > {
318+ let password_size = crate :: buffer_len_to_i32 ( password. len ( ) ) ?;
319+ let salt_size = crate :: buffer_len_to_i32 ( salt. len ( ) ) ?;
320+ let out_size = crate :: buffer_len_to_i32 ( out. len ( ) ) ?;
321+ let rc = unsafe {
322+ sys:: wc_scrypt ( out. as_mut_ptr ( ) , password. as_ptr ( ) , password_size,
323+ salt. as_ptr ( ) , salt_size, cost, block_size, parallel, out_size)
324+ } ;
325+ if rc != 0 {
326+ return Err ( rc) ;
327+ }
328+ Ok ( ( ) )
329+ }
330+
331+ /// Implement the scrypt password-based key derivation function as defined
332+ /// in RFC 7914. This variant takes the iteration count `N` directly
333+ /// instead of `log2(N)`.
334+ ///
335+ /// # Parameters
336+ ///
337+ /// * `password`: Password to use for key derivation.
338+ /// * `salt`: Salt value to use for key derivation.
339+ /// * `iterations`: Iteration count (`N`). Must be a power of two greater
340+ /// than 1.
341+ /// * `block_size`: Number of 128-byte octets in a working block (the `r`
342+ /// parameter from RFC 7914). Must be in `1..=8`.
343+ /// * `parallel`: Number of parallel mix operations to perform (the `p`
344+ /// parameter from RFC 7914). This implementation does not use threads.
345+ /// * `out`: Output buffer in which to store the derived key.
346+ ///
347+ /// # Returns
348+ ///
349+ /// Returns either Ok(()) on success or Err(e) containing the wolfSSL
350+ /// library error code value.
351+ ///
352+ /// # Example
353+ ///
354+ /// ```rust
355+ /// #[cfg(kdf_scrypt)]
356+ /// {
357+ /// use wolfssl_wolfcrypt::kdf::scrypt_ex;
358+ /// let password = b"password";
359+ /// let salt = b"NaCl";
360+ /// let mut keyout = [0u8; 64];
361+ /// scrypt_ex(password, salt, 1024, 8, 16, &mut keyout).expect("Error with scrypt_ex()");
362+ /// }
363+ /// ```
364+ #[ cfg( kdf_scrypt) ]
365+ pub fn scrypt_ex ( password : & [ u8 ] , salt : & [ u8 ] , iterations : u32 ,
366+ block_size : i32 , parallel : i32 , out : & mut [ u8 ] ) -> Result < ( ) , i32 > {
367+ let password_size = crate :: buffer_len_to_i32 ( password. len ( ) ) ?;
368+ let salt_size = crate :: buffer_len_to_i32 ( salt. len ( ) ) ?;
369+ let out_size = crate :: buffer_len_to_i32 ( out. len ( ) ) ?;
370+ let rc = unsafe {
371+ sys:: wc_scrypt_ex ( out. as_mut_ptr ( ) , password. as_ptr ( ) , password_size,
372+ salt. as_ptr ( ) , salt_size, iterations, block_size, parallel, out_size)
373+ } ;
374+ if rc != 0 {
375+ return Err ( rc) ;
376+ }
377+ Ok ( ( ) )
378+ }
379+
272380/// Perform RFC 5869 HKDF-Extract operation for TLS v1.3 key derivation.
273381///
274382/// # Parameters
0 commit comments