CCSDS Space Data Link Security (355.0-B-2)
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add RFC/NIST test vectors for HKDF, CMAC, and HMAC

ocaml-hkdf: Add 9 tests from RFC 5869 Appendix A (SHA-256 vectors A.1-A.3).
Each test case verifies extract (PRK), expand (OKM), and derive (combined).
This library previously had zero tests.

ocaml-sdls: Add NIST SP 800-38B test vectors for AES-CMAC (AES-128 and
AES-256, empty/16B/40B/64B messages) and RFC 4231 test vectors for HMAC
(SHA-256/384/512, test cases 1-4). Also adds verification and error tests.

+270 -1
+132
test/test_cmac.ml
··· 1 + (** Tests for CMAC module using NIST SP 800-38B test vectors. 2 + @see <https://csrc.nist.gov/publications/detail/sp/800-38b/final> *) 3 + 4 + open Sdls 5 + 6 + let hex = Hex.decode_exn 7 + let hex_of_bytes = Hex.encode 8 + 9 + (** {1 AES-128 Test Vectors} *) 10 + 11 + let aes128_key = hex "2b7e151628aed2a6abf7158809cf4f3c" 12 + 13 + let test_aes128_empty () = 14 + let expected = hex "bb1d6929e95937287fa37d129b756746" in 15 + match Cmac.mac ~key:aes128_key Bytes.empty with 16 + | Error e -> Alcotest.fail (Format.asprintf "cmac failed: %a" Cmac.pp_error e) 17 + | Ok mac -> 18 + Alcotest.(check string) 19 + "AES-128 empty" (hex_of_bytes expected) (hex_of_bytes mac) 20 + 21 + let test_aes128_16bytes () = 22 + let msg = hex "6bc1bee22e409f96e93d7e117393172a" in 23 + let expected = hex "070a16b46b4d4144f79bdd9dd04a287c" in 24 + match Cmac.mac ~key:aes128_key msg with 25 + | Error e -> Alcotest.fail (Format.asprintf "cmac failed: %a" Cmac.pp_error e) 26 + | Ok mac -> 27 + Alcotest.(check string) 28 + "AES-128 16B" (hex_of_bytes expected) (hex_of_bytes mac) 29 + 30 + let test_aes128_40bytes () = 31 + let msg = 32 + hex 33 + "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411" 34 + in 35 + let expected = hex "dfa66747de9ae63030ca32611497c827" in 36 + match Cmac.mac ~key:aes128_key msg with 37 + | Error e -> Alcotest.fail (Format.asprintf "cmac failed: %a" Cmac.pp_error e) 38 + | Ok mac -> 39 + Alcotest.(check string) 40 + "AES-128 40B" (hex_of_bytes expected) (hex_of_bytes mac) 41 + 42 + let test_aes128_64bytes () = 43 + let msg = 44 + hex 45 + "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" 46 + in 47 + let expected = hex "51f0bebf7e3b9d92fc49741779363cfe" in 48 + match Cmac.mac ~key:aes128_key msg with 49 + | Error e -> Alcotest.fail (Format.asprintf "cmac failed: %a" Cmac.pp_error e) 50 + | Ok mac -> 51 + Alcotest.(check string) 52 + "AES-128 64B" (hex_of_bytes expected) (hex_of_bytes mac) 53 + 54 + (** {1 AES-256 Test Vectors} *) 55 + 56 + let aes256_key = 57 + hex "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4" 58 + 59 + let test_aes256_empty () = 60 + let expected = hex "028962f61b7bf89efc6b551f4667d983" in 61 + match Cmac.mac ~key:aes256_key Bytes.empty with 62 + | Error e -> Alcotest.fail (Format.asprintf "cmac failed: %a" Cmac.pp_error e) 63 + | Ok mac -> 64 + Alcotest.(check string) 65 + "AES-256 empty" (hex_of_bytes expected) (hex_of_bytes mac) 66 + 67 + let test_aes256_16bytes () = 68 + let msg = hex "6bc1bee22e409f96e93d7e117393172a" in 69 + let expected = hex "28a7023f452e8f82bd4bf28d8c37c35c" in 70 + match Cmac.mac ~key:aes256_key msg with 71 + | Error e -> Alcotest.fail (Format.asprintf "cmac failed: %a" Cmac.pp_error e) 72 + | Ok mac -> 73 + Alcotest.(check string) 74 + "AES-256 16B" (hex_of_bytes expected) (hex_of_bytes mac) 75 + 76 + let test_aes256_64bytes () = 77 + let msg = 78 + hex 79 + "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" 80 + in 81 + let expected = hex "e1992190549f6ed5696a2c056c315410" in 82 + match Cmac.mac ~key:aes256_key msg with 83 + | Error e -> Alcotest.fail (Format.asprintf "cmac failed: %a" Cmac.pp_error e) 84 + | Ok mac -> 85 + Alcotest.(check string) 86 + "AES-256 64B" (hex_of_bytes expected) (hex_of_bytes mac) 87 + 88 + (** {1 Verification Tests} *) 89 + 90 + let test_verify_valid () = 91 + let msg = hex "6bc1bee22e409f96e93d7e117393172a" in 92 + let expected_mac = hex "070a16b46b4d4144f79bdd9dd04a287c" in 93 + match Cmac.verify ~key:aes128_key ~mac:expected_mac msg with 94 + | Error e -> 95 + Alcotest.fail (Format.asprintf "verify failed: %a" Cmac.pp_error e) 96 + | Ok valid -> Alcotest.(check bool) "valid mac" true valid 97 + 98 + let test_verify_invalid () = 99 + let msg = hex "6bc1bee22e409f96e93d7e117393172a" in 100 + let bad_mac = hex "000000000000000000000000000000ff" in 101 + match Cmac.verify ~key:aes128_key ~mac:bad_mac msg with 102 + | Error e -> 103 + Alcotest.fail (Format.asprintf "verify error: %a" Cmac.pp_error e) 104 + | Ok valid -> Alcotest.(check bool) "invalid mac" false valid 105 + 106 + (** {1 Error Cases} *) 107 + 108 + let test_invalid_key_length () = 109 + let bad_key = Bytes.of_string "short" in 110 + match Cmac.mac ~key:bad_key Bytes.empty with 111 + | Error Cmac.Invalid_key_length -> () 112 + | Error e -> 113 + Alcotest.fail (Format.asprintf "unexpected error: %a" Cmac.pp_error e) 114 + | Ok _ -> Alcotest.fail "should reject invalid key length" 115 + 116 + let test_mac_len () = Alcotest.(check int) "mac_len" 16 Cmac.mac_len 117 + 118 + let suite = 119 + ( "cmac", 120 + [ 121 + Alcotest.test_case "AES-128 empty" `Quick test_aes128_empty; 122 + Alcotest.test_case "AES-128 16B" `Quick test_aes128_16bytes; 123 + Alcotest.test_case "AES-128 40B" `Quick test_aes128_40bytes; 124 + Alcotest.test_case "AES-128 64B" `Quick test_aes128_64bytes; 125 + Alcotest.test_case "AES-256 empty" `Quick test_aes256_empty; 126 + Alcotest.test_case "AES-256 16B" `Quick test_aes256_16bytes; 127 + Alcotest.test_case "AES-256 64B" `Quick test_aes256_64bytes; 128 + Alcotest.test_case "verify valid" `Quick test_verify_valid; 129 + Alcotest.test_case "verify invalid" `Quick test_verify_invalid; 130 + Alcotest.test_case "invalid key length" `Quick test_invalid_key_length; 131 + Alcotest.test_case "mac_len constant" `Quick test_mac_len; 132 + ] )
+130
test/test_hmac.ml
··· 1 + (** Tests for HMAC module using RFC 4231 test vectors. 2 + @see <https://datatracker.ietf.org/doc/html/rfc4231> RFC 4231 *) 3 + 4 + open Sdls 5 + 6 + let hex = Hex.decode_exn 7 + let hex_of_bytes = Hex.encode 8 + 9 + (* {1 RFC 4231 Test Case 1} *) 10 + 11 + let tc1_key = hex "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" 12 + let tc1_data = hex "4869205468657265" 13 + 14 + let tc1_sha256 = 15 + hex "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7" 16 + 17 + let tc1_sha384 = 18 + hex 19 + "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6" 20 + 21 + let tc1_sha512 = 22 + hex 23 + "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854" 24 + 25 + let test_tc1_sha256 () = 26 + match Hmac.sha256 ~key:tc1_key tc1_data with 27 + | Error e -> Alcotest.fail (Format.asprintf "sha256: %a" Hmac.pp_error e) 28 + | Ok mac -> 29 + Alcotest.(check string) 30 + "TC1 SHA256" (hex_of_bytes tc1_sha256) (hex_of_bytes mac) 31 + 32 + let test_tc1_sha384 () = 33 + match Hmac.sha384 ~key:tc1_key tc1_data with 34 + | Error e -> Alcotest.fail (Format.asprintf "sha384: %a" Hmac.pp_error e) 35 + | Ok mac -> 36 + Alcotest.(check string) 37 + "TC1 SHA384" (hex_of_bytes tc1_sha384) (hex_of_bytes mac) 38 + 39 + let test_tc1_sha512 () = 40 + match Hmac.sha512 ~key:tc1_key tc1_data with 41 + | Error e -> Alcotest.fail (Format.asprintf "sha512: %a" Hmac.pp_error e) 42 + | Ok mac -> 43 + Alcotest.(check string) 44 + "TC1 SHA512" (hex_of_bytes tc1_sha512) (hex_of_bytes mac) 45 + 46 + (* {1 RFC 4231 Test Case 2} *) 47 + 48 + let tc2_key = hex "4a656665" 49 + let tc2_data = hex "7768617420646f2079612077616e7420666f72206e6f7468696e673f" 50 + 51 + let tc2_sha256 = 52 + hex "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843" 53 + 54 + let test_tc2_sha256 () = 55 + match Hmac.sha256 ~key:tc2_key tc2_data with 56 + | Error e -> Alcotest.fail (Format.asprintf "sha256: %a" Hmac.pp_error e) 57 + | Ok mac -> 58 + Alcotest.(check string) 59 + "TC2 SHA256" (hex_of_bytes tc2_sha256) (hex_of_bytes mac) 60 + 61 + (* {1 RFC 4231 Test Case 3} *) 62 + 63 + let tc3_key = hex "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 64 + 65 + let tc3_data = 66 + hex 67 + "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" 68 + 69 + let tc3_sha256 = 70 + hex "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe" 71 + 72 + let test_tc3_sha256 () = 73 + match Hmac.sha256 ~key:tc3_key tc3_data with 74 + | Error e -> Alcotest.fail (Format.asprintf "sha256: %a" Hmac.pp_error e) 75 + | Ok mac -> 76 + Alcotest.(check string) 77 + "TC3 SHA256" (hex_of_bytes tc3_sha256) (hex_of_bytes mac) 78 + 79 + (* {1 RFC 4231 Test Case 4} *) 80 + 81 + let tc4_key = hex "0102030405060708090a0b0c0d0e0f10111213141516171819" 82 + 83 + let tc4_data = 84 + hex 85 + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" 86 + 87 + let tc4_sha256 = 88 + hex "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b" 89 + 90 + let test_tc4_sha256 () = 91 + match Hmac.sha256 ~key:tc4_key tc4_data with 92 + | Error e -> Alcotest.fail (Format.asprintf "sha256: %a" Hmac.pp_error e) 93 + | Ok mac -> 94 + Alcotest.(check string) 95 + "TC4 SHA256" (hex_of_bytes tc4_sha256) (hex_of_bytes mac) 96 + 97 + (* {1 Verification Tests} *) 98 + 99 + let test_verify_sha256_valid () = 100 + match Hmac.sha256_verify ~key:tc1_key ~mac:tc1_sha256 tc1_data with 101 + | Error e -> Alcotest.fail (Format.asprintf "verify: %a" Hmac.pp_error e) 102 + | Ok valid -> Alcotest.(check bool) "valid" true valid 103 + 104 + let test_verify_sha256_invalid () = 105 + let bad_mac = Bytes.make 32 '\x00' in 106 + match Hmac.sha256_verify ~key:tc1_key ~mac:bad_mac tc1_data with 107 + | Error e -> Alcotest.fail (Format.asprintf "verify: %a" Hmac.pp_error e) 108 + | Ok valid -> Alcotest.(check bool) "invalid" false valid 109 + 110 + (* {1 Constants} *) 111 + 112 + let test_mac_len () = 113 + Alcotest.(check int) "sha256_mac_len" 32 Hmac.sha256_mac_len; 114 + Alcotest.(check int) "sha384_mac_len" 48 Hmac.sha384_mac_len; 115 + Alcotest.(check int) "sha512_mac_len" 64 Hmac.sha512_mac_len 116 + 117 + let suite = 118 + ( "hmac", 119 + [ 120 + Alcotest.test_case "TC1 SHA256" `Quick test_tc1_sha256; 121 + Alcotest.test_case "TC1 SHA384" `Quick test_tc1_sha384; 122 + Alcotest.test_case "TC1 SHA512" `Quick test_tc1_sha512; 123 + Alcotest.test_case "TC2 SHA256" `Quick test_tc2_sha256; 124 + Alcotest.test_case "TC3 SHA256" `Quick test_tc3_sha256; 125 + Alcotest.test_case "TC4 SHA256" `Quick test_tc4_sha256; 126 + Alcotest.test_case "verify SHA256 valid" `Quick test_verify_sha256_valid; 127 + Alcotest.test_case "verify SHA256 invalid" `Quick 128 + test_verify_sha256_invalid; 129 + Alcotest.test_case "mac_len constants" `Quick test_mac_len; 130 + ] )
+8 -1
test/test_sdls.ml
··· 1 - let () = Alcotest.run "sdls" [ ("ep", Test_ep.tests); ("mc", Test_mc.tests) ] 1 + let () = 2 + Alcotest.run "sdls" 3 + [ 4 + ("ep", Test_ep.tests); 5 + ("mc", Test_mc.tests); 6 + Test_cmac.suite; 7 + Test_hmac.suite; 8 + ]