hkdf_tests.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright 2015 Brian Smith.
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
  8. // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
  10. // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. use ring::{digest, error, hkdf, test, test_file};
  15. #[cfg(target_arch = "wasm32")]
  16. use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
  17. #[cfg(target_arch = "wasm32")]
  18. wasm_bindgen_test_configure!(run_in_browser);
  19. #[test]
  20. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
  21. fn hkdf_tests() {
  22. test::run(test_file!("hkdf_tests.txt"), |section, test_case| {
  23. assert_eq!(section, "");
  24. let alg = {
  25. let digest_alg = test_case
  26. .consume_digest_alg("Hash")
  27. .ok_or(error::Unspecified)?;
  28. if digest_alg == &digest::SHA256 {
  29. hkdf::HKDF_SHA256
  30. } else {
  31. // TODO: add test vectors for other algorithms
  32. panic!("unsupported algorithm: {:?}", digest_alg);
  33. }
  34. };
  35. let secret = test_case.consume_bytes("IKM");
  36. let salt = test_case.consume_bytes("salt");
  37. let info = test_case.consume_bytes("info");
  38. let _ = test_case.consume_bytes("PRK");
  39. let expected_out = test_case.consume_bytes("OKM");
  40. let salt = hkdf::Salt::new(alg, &salt);
  41. // TODO: test multi-part info, especially with empty parts.
  42. let My(out) = salt
  43. .extract(&secret)
  44. .expand(&[&info], My(expected_out.len()))
  45. .unwrap()
  46. .into();
  47. assert_eq!(out, expected_out);
  48. Ok(())
  49. });
  50. }
  51. #[test]
  52. #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
  53. fn hkdf_output_len_tests() {
  54. for &alg in &[hkdf::HKDF_SHA256, hkdf::HKDF_SHA384, hkdf::HKDF_SHA512] {
  55. const MAX_BLOCKS: usize = 255;
  56. let salt = hkdf::Salt::new(alg, &[]);
  57. let prk = salt.extract(&[]); // TODO: enforce minimum length.
  58. {
  59. // Test zero length.
  60. let okm = prk.expand(&[b"info"], My(0)).unwrap();
  61. let result: My<Vec<u8>> = okm.into();
  62. assert_eq!(&result.0, &[]);
  63. }
  64. let max_out_len = MAX_BLOCKS * alg.hmac_algorithm().digest_algorithm().output_len;
  65. {
  66. // Test maximum length output succeeds.
  67. let okm = prk.expand(&[b"info"], My(max_out_len)).unwrap();
  68. let result: My<Vec<u8>> = okm.into();
  69. assert_eq!(result.0.len(), max_out_len);
  70. }
  71. {
  72. // Test too-large output fails.
  73. assert!(prk.expand(&[b"info"], My(max_out_len + 1)).is_err());
  74. }
  75. {
  76. // Test length mismatch (smaller).
  77. let okm = prk.expand(&[b"info"], My(2)).unwrap();
  78. let mut buf = [0u8; 1];
  79. assert_eq!(okm.fill(&mut buf), Err(error::Unspecified));
  80. }
  81. {
  82. // Test length mismatch (larger).
  83. let okm = prk.expand(&[b"info"], My(2)).unwrap();
  84. let mut buf = [0u8; 3];
  85. assert_eq!(okm.fill(&mut buf), Err(error::Unspecified));
  86. }
  87. {
  88. // Control for above two tests.
  89. let okm = prk.expand(&[b"info"], My(2)).unwrap();
  90. let mut buf = [0u8; 2];
  91. assert_eq!(okm.fill(&mut buf), Ok(()));
  92. }
  93. }
  94. }
  95. /// Generic newtype wrapper that lets us implement traits for externally-defined
  96. /// types.
  97. #[derive(Debug, PartialEq)]
  98. struct My<T: core::fmt::Debug + PartialEq>(T);
  99. impl hkdf::KeyType for My<usize> {
  100. fn len(&self) -> usize {
  101. self.0
  102. }
  103. }
  104. impl From<hkdf::Okm<'_, My<usize>>> for My<Vec<u8>> {
  105. fn from(okm: hkdf::Okm<My<usize>>) -> Self {
  106. let mut r = vec![0u8; okm.len().0];
  107. okm.fill(&mut r).unwrap();
  108. My(r)
  109. }
  110. }