diff --git a/Cargo.lock b/Cargo.lock index 2f35b48533..0f0eddc9be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "aead" version = "0.5.2" @@ -53,20 +38,29 @@ dependencies = [ "subtle", ] +[[package]] +name = "aes-kw" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fa2b352dcefb5f7f3a5fb840e02665d311d878955380515e4fd50095dd3d8c" +dependencies = [ + "aes", +] + [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.6.19" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -79,9 +73,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -94,35 +88,36 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.9" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "aproxy" version = "0.1.0" dependencies = [ "anyhow", + "base64", "clap", "kbs-types", "libaproxy", @@ -133,33 +128,24 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] [[package]] -name = "autocfg" -version = "1.5.0" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] -name = "backtrace" -version = "0.3.75" +name = "autocfg" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base16ct" @@ -185,7 +171,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools", @@ -229,9 +215,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "block-buffer" @@ -247,7 +233,7 @@ name = "bootlib" version = "0.1.0" dependencies = [ "uuid", - "zerocopy 0.8.26", + "zerocopy 0.8.30", ] [[package]] @@ -264,9 +250,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "camellia" @@ -296,10 +282,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.30" +version = "1.2.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" +checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -325,9 +312,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cipher" @@ -353,9 +340,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.41" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", "clap_derive", @@ -363,9 +350,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.41" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", @@ -375,9 +362,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.41" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", @@ -387,24 +374,24 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmpa" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9faa1daaed3d529f0d21cf054f3408145917ea1b6ac87f57f45f10b6b4cd3e39" +checksum = "1be785eeeffa3c5f99e7f71775051590c14b68b7f07fdf85641648d89dc9bf16" dependencies = [ "zeroize", ] [[package]] name = "cocoon-tpm-crypto" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cf4b0ad6a24beadf53f694d96cdf2d0f3791e0ad1763d460bb0f78a0cae65ef" +checksum = "1b7633b7e5996b4b5d15929736d10910c087713a9bdf9b7a05c1f16d192ae413" dependencies = [ "aes", "camellia", @@ -416,7 +403,7 @@ dependencies = [ "cocoon-tpm-utils-common", "crypto-common", "digest", - "generic-array 1.2.0", + "generic-array 1.3.5", "hmac", "ofb", "sha2", @@ -430,15 +417,12 @@ name = "cocoon-tpm-tpm2-interface" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd87d8fabcfd5949ef574c04814c6c783858310bdcc58d807003fc8da56eac23" -dependencies = [ - "zeroize", -] [[package]] name = "cocoon-tpm-utils-common" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47c0d6914fa0e6d7e03d39838585b14542f018933a38edb66d5254218986f66" +checksum = "19fa8730c221b252c85b70e895101b9022cd5777d8c8d3c35e9f92d1a27d1b45" dependencies = [ "cmpa", "zeroize", @@ -450,6 +434,15 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "concat-kdf" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d72c1252426a83be2092dd5884a5f6e3b8e7180f6891b6263d2c21b92ec8816" +dependencies = [ + "digest", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -490,7 +483,7 @@ name = "cpuarch" version = "0.1.0" dependencies = [ "bitfield-struct 0.6.2", - "zerocopy 0.8.26", + "zerocopy 0.8.30", ] [[package]] @@ -525,9 +518,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array 0.14.7", "typenum", @@ -555,18 +548,18 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", ] [[package]] name = "derive_arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", @@ -598,9 +591,9 @@ dependencies = [ [[package]] name = "document-features" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" dependencies = [ "litrs", ] @@ -629,7 +622,7 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" name = "elf" version = "0.1.0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", ] [[package]] @@ -675,16 +668,16 @@ dependencies = [ ] [[package]] -name = "fnv" -version = "1.0.7" +name = "find-msvc-tools" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -776,10 +769,11 @@ dependencies = [ [[package]] name = "generic-array" -version = "1.2.0" +version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c8444bc9d71b935156cc0ccab7f622180808af7867b1daae6547d773591703" +checksum = "eaf57c49a95fd1fe24b90b3033bee6dc7e8f1288d51494cb44e627c295e38542" dependencies = [ + "rustversion", "typenum", ] @@ -791,19 +785,19 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", ] [[package]] @@ -816,17 +810,11 @@ dependencies = [ "polyval", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "group" @@ -877,12 +865,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -917,18 +904,20 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", "http", "http-body", "httparse", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -936,9 +925,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.15" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df" +checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" dependencies = [ "base64", "bytes", @@ -960,9 +949,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -973,9 +962,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -986,11 +975,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -1001,42 +989,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -1046,9 +1030,9 @@ dependencies = [ [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -1080,7 +1064,7 @@ dependencies = [ "static_assertions", "thiserror", "tracing", - "zerocopy 0.8.26", + "zerocopy 0.8.30", ] [[package]] @@ -1092,7 +1076,7 @@ dependencies = [ "bitfield-struct 0.10.1", "open-enum", "static_assertions", - "zerocopy 0.8.26", + "zerocopy 0.8.30", ] [[package]] @@ -1104,7 +1088,7 @@ dependencies = [ "igvm", "igvm_defs", "uuid", - "zerocopy 0.8.26", + "zerocopy 0.8.30", ] [[package]] @@ -1116,7 +1100,7 @@ dependencies = [ "igvm_defs", "p384", "sha2", - "zerocopy 0.8.26", + "zerocopy 0.8.30", ] [[package]] @@ -1147,17 +1131,6 @@ dependencies = [ "memoffset", ] -[[package]] -name = "io-uring" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -1166,9 +1139,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" dependencies = [ "memchr", "serde", @@ -1176,9 +1149,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" @@ -1197,19 +1170,19 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -1217,13 +1190,16 @@ dependencies = [ [[package]] name = "kbs-types" -version = "0.10.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db954f164e19a63a1eb7c04c46511167d68a5eb5025d4a435c1ba297f00dbf4" +checksum = "6b02b8dec349b64f7bc236309667cd6f8b4a9c7e5d7bc4677c38b0dd5333b46c" dependencies = [ "base64", "serde", "serde_json", + "sha2", + "sm3", + "strum", "thiserror", ] @@ -1240,9 +1216,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libfuzzer-sys" @@ -1256,12 +1232,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.2", + "windows-link", ] [[package]] @@ -1273,21 +1249,21 @@ dependencies = [ [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "litrs" -version = "0.4.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "managed" @@ -1297,9 +1273,9 @@ checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" @@ -1325,24 +1301,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - [[package]] name = "mio" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -1370,15 +1337,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "ofb" version = "0.6.1" @@ -1396,9 +1354,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "opaque-debug" @@ -1464,9 +1422,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project-lite" @@ -1504,9 +1462,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -1519,9 +1477,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "prettyplease" -version = "0.2.35" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn", @@ -1563,9 +1521,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -1593,9 +1551,9 @@ checksum = "7cc2191ec1fd850e3ede4cf09ccfd40a33df561111f73e96e1b7c3f9eee31328" [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -1605,9 +1563,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -1616,9 +1574,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "release" @@ -1626,9 +1584,9 @@ version = "0.1.0" [[package]] name = "reqwest" -version = "0.12.22" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "base64", "bytes", @@ -1670,12 +1628,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "rustc-demangle" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -1693,9 +1645,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -1719,9 +1671,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "seq-macro" @@ -1731,18 +1683,28 @@ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1751,14 +1713,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -1806,6 +1769,15 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +[[package]] +name = "sm3" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebb9a3b702d0a7e33bc4d85a14456633d2b165c2ad839c5fd9a8417c1ab15860" +dependencies = [ + "digest", +] + [[package]] name = "sm4" version = "0.5.1" @@ -1823,12 +1795,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.10" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -1843,9 +1815,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stage1" @@ -1866,6 +1838,27 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "subtle" version = "2.6.1" @@ -1876,15 +1869,15 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" name = "svsm" version = "0.1.0" dependencies = [ - "aes", "aes-gcm", - "base64", + "aes-kw", "bitfield-struct 0.6.2", - "bitflags 2.9.1", + "bitflags 2.10.0", "bootlib", "cocoon-tpm-crypto", "cocoon-tpm-tpm2-interface", "cocoon-tpm-utils-common", + "concat-kdf", "cpuarch", "elf", "gdbstub", @@ -1911,7 +1904,7 @@ dependencies = [ "verus_stub", "virtio-drivers", "vstd", - "zerocopy 0.8.26", + "zerocopy 0.8.30", ] [[package]] @@ -1925,9 +1918,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -1958,7 +1951,7 @@ dependencies = [ name = "syscall" version = "0.1.0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", ] [[package]] @@ -1967,18 +1960,18 @@ version = "0.1.0" [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -1987,9 +1980,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", @@ -2002,15 +1995,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -2018,9 +2011,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -2028,18 +2021,15 @@ dependencies = [ [[package]] name = "tokio" -version = "1.46.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", - "io-uring", "libc", "mio", "pin-project-lite", - "slab", "socket2", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2059,11 +2049,11 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "9cf146f99d442e8e68e585f5d798ccd3cad9a7835b917e09728880a862706456" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "bytes", "futures-util", "http", @@ -2126,15 +2116,15 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "universal-hash" @@ -2148,13 +2138,14 @@ dependencies = [ [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -2185,9 +2176,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" [[package]] name = "verify_external" @@ -2223,9 +2214,9 @@ checksum = "e9d00c22a221fbf8b3398002ebdd1c89017e5381c2f05d6933a3706d87e90e14" [[package]] name = "verus_builtin_macros" -version = "0.0.0-2025-11-16-0050" +version = "0.0.0-2025-11-24-2240" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b81815a92a215853f2c9dc87967eac087c3a5126f0acc4c11c6175b9f2b633d" +checksum = "5713bf8de72210a2de75e1c40367824974fea3eaf769351698ee4eae668c7e57" dependencies = [ "proc-macro2", "quote", @@ -2254,9 +2245,9 @@ dependencies = [ [[package]] name = "verus_state_machines_macros" -version = "0.0.0-2025-11-16-0050" +version = "0.0.0-2025-11-23-0053" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9b5f719e2d4fc80ffcff723da75c31a7ea1419220627917e152b2d7cae2fbdc" +checksum = "7f0d2b64ab30b4d79d55b8ba83df03dcb6a550805d0f9586f700b4bb6e82be8a" dependencies = [ "indexmap", "proc-macro2", @@ -2288,17 +2279,17 @@ dependencies = [ name = "virtio-drivers" version = "0.7.5" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "enumn", "log", - "zerocopy 0.8.26", + "zerocopy 0.8.30", ] [[package]] name = "vstd" -version = "0.0.0-2025-11-16-0050" +version = "0.0.0-2025-11-24-2240" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78daf1e3f8fde46c7ccbdd80d1d95875d8be3fe9b02f5f827d798cbecad47893" +checksum = "2014cfb31f9dec56e9ce777c4d931b9f45c49b9f9a54de9aedfdf7bb83421490" dependencies = [ "verus_builtin", "verus_builtin_macros", @@ -2321,45 +2312,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" dependencies = [ "cfg-if", "js-sys", @@ -2370,9 +2348,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2380,196 +2358,136 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.52.6" +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows-link", ] [[package]] name = "windows-targets" -version = "0.53.2" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "xbuild" @@ -2582,11 +2500,10 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -2594,9 +2511,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -2616,11 +2533,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c" dependencies = [ - "zerocopy-derive 0.8.26", + "zerocopy-derive 0.8.30", ] [[package]] @@ -2636,9 +2553,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5" dependencies = [ "proc-macro2", "quote", @@ -2668,15 +2585,15 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -2685,9 +2602,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -2696,9 +2613,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 8b80a7155a..0ace007d50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,8 +59,8 @@ release = { path = "release" } virtio-drivers = { path = "virtio-drivers" } # crates.io -aes = "0.8.4" aes-gcm = { version = "0.10.3", default-features = false } +aes-kw = { version = "0.2.1", default-features = false } arbitrary = "1.3.0" base64 = { version = "0.22.1", default-features = false } bitfield-struct = "0.6.2" @@ -69,12 +69,13 @@ clap = { version = "4.4.14", default-features = false } cocoon-tpm-crypto = { version = "0.1.0", default-features = false } cocoon-tpm-tpm2-interface = { version = "0.1.0", default-features = false } cocoon-tpm-utils-common = { version = "0.1.0", default-features = false } +concat-kdf = "0.1.0" gdbstub = { version = "0.6.6", default-features = false } gdbstub_arch = { version = "0.2.4" } igvm = { version = "0.4.0", default-features = false } igvm_defs = { version = "0.4.0", default-features = false } intrusive-collections = "0.9.6" -kbs-types = { version = "0.10.0", default-features = false } +kbs-types = { version = "0.14.0", default-features = false } libfuzzer-sys = "0.4" log = "0.4.17" p384 = { version = "0.13.0" } diff --git a/Documentation/docs/developer/ATTESTATION.md b/Documentation/docs/developer/ATTESTATION.md index 155d940013..5f50bbcd5a 100644 --- a/Documentation/docs/developer/ATTESTATION.md +++ b/Documentation/docs/developer/ATTESTATION.md @@ -36,14 +36,169 @@ is fresh and legitimate. The negotiation phase returns the parameters that SVSM should include in its attestation evidence based on the underlying attestation server and protocol. +In the negotiation phase, a `NegotiationRequest` is sent from SVSM to the proxy. +An example `NegotiationRequest` is shown below. +```json +{ + "version": [0,1,0], + "tee": "snp", +} +``` + +- `version`: The SVSM attestation protocol version to use. In place to ensure +backwards compatibility with updated protocol versions should modifications +occur. The API follows [SemVer](https://semver.org/) and is represented as a +tuple [MAJOR, MINOR, PATCH]. The current version is 0.1.0. +- `tee`: The TEE hardware architecture that SVSM is running on. + +The proxy will then complete the negotiation phase with the remote attestation +server and reply with a list of negotiation parameters that must be included in +the attestation evidence. + +A `NegotiationResponse` is sent from the proxy to SVSM. +An example `NegotiationResponse` is shown below. +```json +{ + "challenge": "oFlY92ZdS3ymzxokYuDzxw==\", + "params": [ + "EcPublicKeyBytes", + "Challenge" + ] +} +``` +- `challenge`: The challenge nonce returned by the remote attestation server +that will likely need to be hashed into the attestation evidence to ensure +freshness. Represented as variably-sized array of bytes. +- `params`: The negotiation parameters. Each `NegotiationParam` represents some +form of data that must be hashed into the attestation evidence. This hash will +be reconstructed by the remote attestation server when the evidence is presented +from SVSM. + +The valid negotiation parameters are as follows: +- `Challenge`: The bytes represented in the `challenge`. +- `EcPublicKeyBytes`: The byte buffers of the public key's x and y coordinates +(in that order). + +SVSM can then collect the attestation evidence (with the negotiation parameters +embedded within the report data) and continue to the attestation phase. + ### Attestation Phase -With all relevant data embedded in TEE evidence, SVSM sends its evidence to the -remote server for evaluation. Upon successful attestation, the proxy will obtain -an encrypted secret (only decryptable by SVSM's TEE private key) for SVSM to -use. For example, SVSM could use this secret to unlock encrypted persistent +With all relevant data embedded in the TEE evidence, SVSM sends the evidence to +the remote server for evaluation. Upon successful attestation, the proxy will +obtain an encrypted secret (only decryptable by SVSM's attestation private key) +for SVSM to use. For example, SVSM could use this secret to unlock encrypted storage. +In the attestation phase, an `AttestationRequest` is sent from SVSM to the proxy. +An example `AttestationRequest` is shown below. +```json +{ + "tee": "snp", + "evidence":{ + "Snp":{ + "report": "AwAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEAAAADAAAAAAAY0QUAAAAAAAAAAAAAAAAAAAAHZTCHj6 + luB8MACrYnlqNmLuBgdclkh4UqGAMdZfMHZ+uVHytFLnvJXLkPx3xMf8p + B7faGTY+Mlwi96geujAbfPKa1C+9Kt7Hts/t0Vp+TKQachyjYCZLBhTV2 + f7zI05r0HlwonTiV/mva7ZwxvdGaAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAACcdt0ZPBJrpXFX6RTFjSItibRTVsXM + Rn/pL/wbViPO6///////////////////////////////////////////A + wAAAAAAF9EZAQEAAAAAAAAAAAAAAAAAAAAAAAAAAACd3vUWsdS5AAdRkM + 51mXGLWEdB7w3CkS2L4/AmeQQPCKQFLcC81HJoD2st3/01IHaqOwGz3Xd + Lb57uqDPWYLxpAwAAAAAAGNEdNwEAHTcBAAMAAAAAABjRAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+InMMSLac18ai1bi + 1kJZISAv0MXt7fBB9do732UwrcjUaxCNxZun8fsAWKXU1LPcAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAz+KTpyaINiKXdTAYhGTMl+g05It+QVEsrZ + 5Vc1LHpng+KO4uFLFw0PLiXbNTwGU8AAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\", + "certs_buf": null + } + }, + "challenge": "oFlY92ZdS3ymzxokYuDzxw==\", + "key":{ + "x": "AeFSAOU2/rtNV4VS0uTr5M729jAU1RIZ+p90kRRbIac6x56y40bG39gc+oxykTITDL + gQER79+kVluCC+Lt6QSfaU\", + "y": "AcBKVeKrw0p+7Nv/JuZMn+zuuQAhpSawoRq3g6Rhc9soXzsPlVLblIEw9muXSNUWbv + fNrLHrmw+qy8lR1o/Kvkys\" + } +} +``` + +- `tee`: The TEE architecture that the evidence should be interpreted as. +- `evidence`: The attestation evidence (i.e. report) from the TEE processor. +Based on the underlying TEE architecture (SEV-SNP being represented in the +example). + +Valid evidence formats are the following: +- `Snp`: SEV-SNP + - `report`: Attestation report bytes. + - `certs_buf`: Optional byte buffer representing SEV-SNP certificate chain + (ARK, ASK, VEK) set by the host hypervisor. + +- `challenge`: The original challenge nonce given in the `NegotiationResponse`. +- `key`: The EC public key that will be used to encrypt secret payloads received +from the remote server upon a successful attestation. Public key x and y +coordinates supplied. + +The proxy will forward the evidence and metadata to the remote attestation +server for evaluation. Upon successful attestation, the proxy should be able to +retrieve some secret payload from the remote server. The proxy will retrieve +this secret and reply to SVSM with an `AttestationResponse`. +An example `AttestationResponse` is shown below. +```json +{ + "success": true, + "secret": "aQ8Kt1EqRlj54Me3\", + "decryption":{ + "epk":{ + "x": "AeFSAOU2/rtNV4VS0uTr5M729jAU1RIZ+p90kRRbIac6x56y40bG39gc+oxykT + ITDLgQER79+kVluCC+Lt6QSfaU\", + "y": "ASrjxo2XfkkkNTiq174Uhj++eNgwzt1iA/hRrYA/6tn8i4ZgPjIiBT0EybAvn8 + p3JQQmw6QKM38Ck5saMZcWF/4/\" + }, + "wrapped_cek": "wucVMB63/N1jXTtIwF8WIbMU88X2NicJKwkyTX6eE4M4Fu1ZLcLIyA==\", + "aad": "ZXlKaGJHY2lPaUpGUTBSSUxVVlRLMEV5TlRaTFZ5SXNJbVZ1WXlJNklrRXlOVFpI + UTAwaUxDSmxjR3NpT25zaVkzSjJJam9pVUMwMU1qRWlMQ0pyZEhraU9pSkZReUlz + SW5naU9pSkJaVVpUUVU5Vk1sOXlkRTVXTkZaVE1IVlVjalZOTnpJNWFrRlZNVkpK + V2kxd09UQnJVbEppU1dGak5uZzFObmswTUdKSE16bG5ZeTF2ZUhsclZFbFVSRXhu + VVVWU056a3RhMVpzZFVORExVeDBObEZUWm1GVklpd2llU0k2SWtGVGNtcDRiekpZ + Wm10cmEwNVVhWEV4TnpSVmFHb3RMV1ZPWjNkNmRERnBRVjlvVW5KWlFWODJkRzQ0 + YVRSYVoxQnFTV2xDVkRCRmVXSkJkbTQ0Y0ROS1VWRnRkelpSUzAwek9FTnJOWE5o + VFZwalYwWmZORjhpZlgw\", + "iv": "Aqy5VLobeoLXAdiq\", + "tag": "FKsIBoVn03SsONln0y66sw==\" + }, + "token":{ + "Jwt":"test-token" + } +} +``` +- `success`: Indicates if attestation was ultimately successful. +- `secret`: The encrypted secret payload. +- `decryption`: ECDH-ES-A256KW data needed to perform the handshake and derive +the AES key for the encrypted payload. Data is formatted for decryption with +ECDH-ES+A256KW, described in RFC 7518, section 4.6.2. +- `token`: Token returned from server that contains the claims validated in the +attestation. Could be serialized in JSON (JWT) or CBOR (CWT). + +With a successful attestation, SVSM can now use the secret payload for some +purpose (for example, to unlock some persistent state required for booting the +OS) and continue with execution. + ## Attestation Host Proxy As there exists multiple protocols for TEE attestation, the host proxy is built @@ -106,8 +261,7 @@ SEV-SNP machine with an SVSM-enabled kernel. git clone https://github.com/coconut-svsm/kbs-test.git cd kbs-test MEASUREMENT="$(${SVSM}/bin/igvmmeasure --check-kvm ${SVSM}/bin/coconut-qemu.igvm measure -b)" - HEX_EXPECTED_MEASUREMENT="$(echo $MEASUREMENT | xxd -p)" - cargo run -- --measurement $HEX_EXPECTED_MEASUREMENT + cargo run -- --measurement $MEASUREMENT --secret $HEX_SECRET ``` This will run the `kbs-test` server at . diff --git a/aproxy/Cargo.toml b/aproxy/Cargo.toml index 7dacfeb76f..1f79e7bbf9 100644 --- a/aproxy/Cargo.toml +++ b/aproxy/Cargo.toml @@ -5,10 +5,11 @@ edition = "2021" [target.'cfg(all(target_os = "linux"))'.dependencies] reqwest = { version = "0.12.9", default-features = false, features = ["blocking", "cookies", "json"] } -kbs-types = "0.10.0" +kbs-types.workspace = true [dependencies] anyhow = "1.0.93" +base64 = { workspace = true, features = ["std"] } clap = { version = "4.5", features = ["derive"] } libaproxy.workspace = true serde.workspace = true diff --git a/aproxy/src/backend/kbs.rs b/aproxy/src/backend/kbs.rs new file mode 100644 index 0000000000..d239e18781 --- /dev/null +++ b/aproxy/src/backend/kbs.rs @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2024 Red Hat, Inc +// +// Author: Stefano Garzarella +// Author: Tyler Fanelli + +use super::*; +use anyhow::{bail, Context}; +use base64::{ + prelude::{BASE64_STANDARD, BASE64_URL_SAFE_NO_PAD}, + Engine, +}; +use kbs_types::*; +use reqwest::StatusCode; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +#[derive(Clone, Copy, Debug, Default)] +pub struct KbsProtocol; + +#[derive(Deserialize, Debug)] +struct TokenResponse { + pub token: String, +} + +impl AttestationProtocol for KbsProtocol { + /// KBS servers usually want two components hashed into attestation evidence: the public + /// components of the TEE key, and a nonce provided in the KBS challenge that is fetched + /// from the server's /auth endpoint. These must be hased in order. + /// + /// Make this request to /auth, gather the nonce, and return this in the negotiation + /// parameter for SVSM to hash these components in the attestation evidence. + fn negotiation( + &mut self, + http: &mut HttpClient, + request: NegotiationRequest, + ) -> anyhow::Result { + if request.version != (0, 1, 0) { + return Err(anyhow!("invalid request version")); + } + let req = Request { + version: "0.4.0".to_string(), + tee: request.tee, + extra_params: Value::String("".to_string()), // unused. + }; + + // Fetch challenge containing a nonce from the KBS /auth endpoint. + let http_resp = http + .cli + .post(format!("{}/kbs/v0/auth", http.url)) + .json(&req) + .send() + .context("unable to POST to KBS /auth endpoint")?; + + let text = http_resp + .text() + .context("unable to convert KBS /auth response to text")?; + + let challenge: Challenge = + serde_json::from_str(&text).context("unable to convert KBS /auth response to JSON")?; + + // Challenge nonce is a base64-encoded byte vector. Inform SVSM of this so it could + // decode the bytes and hash them into the TEE evidence. + let params = vec![ + NegotiationParam::EcPublicKeyBytes, + NegotiationParam::Challenge, + ]; + + let resp = NegotiationResponse { + challenge: BASE64_STANDARD + .decode(challenge.nonce) + .context("unable to decode challenge nonce from base64")?, + params, + }; + + Ok(resp) + } + + /// With the serialized TEE evidence and key, complete the attestation. Serialize the evidence + /// and send it to the /attest endpoint of the KBS server. Upon a successful attestation, fetch + /// a secret (identified as "svsm_secret"). If able to successfully fetch the secret, return a + /// successful AttestationResponse with the secret included. + fn attestation( + &mut self, + http: &mut HttpClient, + request: AttestationRequest, + ) -> anyhow::Result { + let evidence: KbsEvidence = (&request).try_into()?; + + // Create a KBS attestation object from the TEE evidence and key. + let attestation = Attestation { + init_data: None, + runtime_data: RuntimeData { + nonce: BASE64_STANDARD.encode(request.challenge), + tee_pubkey: request.key.into(), + }, + tee_evidence: CompositeEvidence { + primary_evidence: serde_json::to_value(&evidence) + .context("unable to serialize attestation evidence to JSON")?, + additional_evidence: String::new(), + }, + }; + + // Attest TEE evidence at KBS /attest endpoint. + let http_resp = http + .cli + .post(format!("{}/kbs/v0/attest", http.url)) + .json(&attestation) + .send() + .context("unable to POST to KBS /attest endpoint")?; + + if http_resp.status() != StatusCode::OK { + return Ok(AttestationResponse { + success: false, + secret: None, + decryption: None, + token: None, + }); + } + + // Get the attestation token from the response. + let token_resp: TokenResponse = serde_json::from_str( + &http_resp + .text() + .context("unable to convert /attest response to text")?, + ) + .context("unable to convert /attest response to JSON object")?; + + // Successful attestation. Fetch the secret (which should be stored at + // /resource/default/sample/test in the KBS server instance. + // + // KBS offers a resource backend repository for testing, which includes the + // default/sample/test file. Fetch the secret "hello, world" from this file to demonstrate + // a secret fetch. + // + // TODO: Further modify this backend to support the KBS module's PKCS11 plugin. + // With this, wrapped secrets can be POSTed to the PKCS11 plugin for unwrapping. + let http_resp = http + .cli + .get(format!("{}/kbs/v0/resource/default/sample/test", http.url)) + .send() + .context("unable to POST to KBS /attest endpoint")?; + + // Unsuccessful attempt at retrieving secret. + if http_resp.status() != StatusCode::OK { + return Ok(AttestationResponse { + success: false, + secret: None, + decryption: None, + token: None, + }); + } + + let text = http_resp + .text() + .context("unable to read KBS /resource response")?; + + let resp: Response = serde_json::from_str(&text) + .context("unable to convert KBS /resource response to KBS Response object")?; + + let epk = unwrap_epk(&resp)?; + let aad = resp + .protected + .generate_aad() + .context("unable to generate AAD")?; + + Ok(AttestationResponse { + success: true, + secret: Some(resp.ciphertext), + decryption: Some(AesGcmData { + epk, + wrapped_cek: resp.encrypted_key, + aad, + iv: resp.iv, + tag: resp.tag, + }), + token: Some(AttestationToken::Jwt(token_resp.token)), + }) + } +} + +fn unwrap_epk(resp: &Response) -> anyhow::Result { + let epk = resp + .protected + .other_fields + .get("epk") + .context("epk not found")?; + + let _crv = epk + .get("crv") + .context("EC crv value not found")? + .as_str() + .context("unable to convert EC crv value to string")?; + + let x = BASE64_URL_SAFE_NO_PAD + .decode( + epk.get("x") + .context("EC x value not found")? + .as_str() + .context("unable to convert EC x value to string")?, + ) + .context("unable to decode EC x value from base64")?; + + let y = BASE64_URL_SAFE_NO_PAD + .decode( + epk.get("y") + .context("EC y value not found")? + .as_str() + .context("unable to convert EC y value to string")?, + ) + .context("unable to decode EC y value from base64")?; + + Ok(EcP256PublicKey { x, y }) +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +enum KbsEvidence { + Snp { + #[serde(rename = "snp-report")] + snp_report: String, + #[serde(rename = "certs-buf")] + certs_buf: Option, + }, +} + +impl TryFrom<&AttestationRequest> for KbsEvidence { + type Error = anyhow::Error; + + // At the moment, only SEV-SNP evidence is allowed. However, preserve the following match + // statement to describe how other TEE architectures would serialize AttestationEvidence. + #[allow(irrefutable_let_patterns)] + fn try_from(data: &AttestationRequest) -> anyhow::Result { + match data.tee { + Tee::Snp => { + let AttestationEvidence::Snp { + ref report, + ref certs_buf, + } = data.evidence + else { + bail!("invalid SEV-SNP evidence") + }; + + Ok(Self::Snp { + snp_report: BASE64_STANDARD.encode(report), + certs_buf: certs_buf.clone().map(|certs| BASE64_STANDARD.encode(certs)), + }) + } + _ => Err(anyhow!("invalid TEE")), + } + } +} diff --git a/aproxy/src/backend/kbs_test.rs b/aproxy/src/backend/kbs_test.rs deleted file mode 100644 index 618419c986..0000000000 --- a/aproxy/src/backend/kbs_test.rs +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: MIT OR Apache-2.0 -// -// Copyright (c) 2024 Red Hat, Inc -// -// Author: Stefano Garzarella -// Author: Tyler Fanelli - -use super::*; -use anyhow::Context; -use kbs_types::*; -use reqwest::StatusCode; -use serde_json::Value; - -#[derive(Clone, Copy, Debug, Default)] -pub struct KbsProtocol; - -impl AttestationProtocol for KbsProtocol { - /// KBS servers usually want two components hashed into attestation evidence: the public - /// components of the TEE key, and a nonce provided in the KBS challenge that is fetched - /// from the server's /auth endpoint. These must be hased in order. - /// - /// Make this request to /auth, gather the nonce, and return this in the negotiation - /// parameter for SVSM to hash these components in the attestation evidence. - fn negotiation( - &mut self, - http: &mut HttpClient, - request: NegotiationRequest, - ) -> anyhow::Result { - if request.version != *"0.1.0" { - return Err(anyhow!("invalid request version")); - } - let req = Request { - version: "0.1.0".to_string(), // unused. - tee: request.tee, - extra_params: Value::String("".to_string()), // unused. - }; - - // Fetch challenge containing a nonce from the KBS /auth endpoint. - let http_resp = http - .cli - .post(format!("{}/kbs/v0/auth", http.url)) - .json(&req) - .send() - .context("unable to POST to KBS /auth endpoint")?; - - let text = http_resp - .text() - .context("unable to convert KBS /auth response to text")?; - - let challenge: Challenge = - serde_json::from_str(&text).context("unable to convert KBS /auth response to JSON")?; - - // Challenge nonce is a base64-encoded byte vector. Inform SVSM of this so it could - // decode the bytes and hash them into the TEE evidence. - let params = vec![ - NegotiationParam::EcPublicKeyBytes, - NegotiationParam::Base64StdBytes(challenge.nonce), - ]; - - let resp = NegotiationResponse { params }; - - Ok(resp) - } - - /// With the serialized TEE evidence and key, complete the attestation. Serialize the evidence - /// and send it to the /attest endpoint of the KBS server. Upon a successful attestation, fetch - /// a secret (identified as "svsm_secret"). If able to successfully fetch the secret, return a - /// successful AttestationResponse with the secret included. - fn attestation( - &mut self, - http: &mut HttpClient, - request: AttestationRequest, - ) -> anyhow::Result { - // Create a KBS attestation object from the TEE evidence and key. - let attestation = Attestation { - tee_pubkey: match request.key { - AttestationKey::EC { - crv, - x_b64url, - y_b64url, - } => TeePubKey::EC { - crv, - alg: "EC".to_string(), - x: x_b64url, - y: y_b64url, - }, - }, - tee_evidence: Value::String(request.evidence), - }; - - // Attest TEE evidence at KBS /attest endpoint. - let http_resp = http - .cli - .post(format!("{}/kbs/v0/attest", http.url)) - .json(&attestation) - .send() - .context("unable to POST to KBS /attest endpoint")?; - - // The JSON response from the /attest endpoint is basically ignored here. Instead, we check - // the HTTP status to indicate successful attestation. - // - // FIXME - if http_resp.status() != StatusCode::OK { - return Ok(AttestationResponse { - success: false, - secret: None, - pub_key: None, - }); - } - - // Successful attestation. Fetch the secret (which should be stored as "svsm_secret" within - // the KBS's RVPS. - let http_resp = http - .cli - .post(format!("{}/kbs/v0/svsm_secret", http.url)) - .send() - .context("unable to POST to KBS /attest endpoint")?; - - // Unsuccessful attempt at retrieving secret. - if http_resp.status() != StatusCode::OK { - return Ok(AttestationResponse { - success: false, - secret: None, - pub_key: None, - }); - } - - let text = http_resp - .text() - .context("unable to read KBS /resource response")?; - - let resp: Response = serde_json::from_str(&text) - .context("unable to convert KBS /resource response to KBS Response object")?; - - let pub_key = { - let val = serde_json::from_slice(&resp.encrypted_key).unwrap(); - let Value::Object(map) = val else { - panic!(); - }; - - let x = map.get("x_b64url").unwrap(); - let Value::String(x) = x else { - panic!(); - }; - - let y = map.get("y_b64url").unwrap(); - let Value::String(y) = y else { - panic!(); - }; - - AttestationKey::EC { - crv: "EC521".to_string(), - x_b64url: x.to_string(), - y_b64url: y.to_string(), - } - }; - - Ok(AttestationResponse { - success: true, - secret: Some(resp.ciphertext), - pub_key: Some(pub_key), - }) - } -} diff --git a/aproxy/src/backend/mod.rs b/aproxy/src/backend/mod.rs index 60a3f67fb9..d275a39c5c 100644 --- a/aproxy/src/backend/mod.rs +++ b/aproxy/src/backend/mod.rs @@ -5,10 +5,10 @@ // Author: Stefano Garzarella // Author: Tyler Fanelli -mod kbs_test; +mod kbs; use anyhow::{anyhow, Context}; -use kbs_test::KbsProtocol; +use kbs::KbsProtocol; use libaproxy::*; use reqwest::{blocking::Client, cookie::Jar}; use std::{str::FromStr, sync::Arc}; @@ -35,13 +35,13 @@ impl HttpClient { // Depending on the underlying protocol of the attestation server, gather negotiation // parameters accordingly. match self.protocol { - Protocol::KbsTest(mut kbs) => kbs.negotiation(self, req), + Protocol::Kbs(mut kbs) => kbs.negotiation(self, req), } } pub fn attestation(&mut self, req: AttestationRequest) -> anyhow::Result { match self.protocol { - Protocol::KbsTest(mut kbs) => kbs.attestation(self, req), + Protocol::Kbs(mut kbs) => kbs.attestation(self, req), } } } @@ -49,7 +49,7 @@ impl HttpClient { /// Attestation Protocol identifier. #[derive(Clone, Copy, Debug)] pub enum Protocol { - KbsTest(KbsProtocol), + Kbs(KbsProtocol), } impl FromStr for Protocol { @@ -57,7 +57,7 @@ impl FromStr for Protocol { fn from_str(s: &str) -> Result { match &s.to_lowercase()[..] { - "kbs-test" => Ok(Self::KbsTest(KbsProtocol)), + "kbs" => Ok(Self::Kbs(KbsProtocol)), _ => Err(anyhow!("invalid backend attestation protocol selected")), } } diff --git a/aproxy/src/main.rs b/aproxy/src/main.rs index 7f3486b2d6..52e9f7c07a 100644 --- a/aproxy/src/main.rs +++ b/aproxy/src/main.rs @@ -20,8 +20,6 @@ struct Args { url: String, /// Backend attestation protocol that the server implements. - /// Supported servers include: - /// kbs-test: https://github.com/tylerfanelli/kbs-test (for testing). #[clap(long = "protocol")] backend: backend::Protocol, diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index f60485ff39..6278c0c5a0 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -25,9 +25,8 @@ libaproxy = { workspace = true, optional = true } elf.workspace = true syscall.workspace = true -aes = { workspace = true, optional = true } aes-gcm = { workspace = true, features = ["aes", "alloc"] } -base64 = { workspace = true, optional = true, features = ["alloc"] } +aes-kw = { workspace = true, optional = true } bitfield-struct.workspace = true bitflags.workspace = true cocoon-tpm-crypto = { workspace = true, features = [ @@ -43,6 +42,7 @@ cocoon-tpm-crypto = { workspace = true, features = [ ], optional = true } cocoon-tpm-tpm2-interface = { workspace = true, optional = true } cocoon-tpm-utils-common = { workspace = true, optional = true } +concat-kdf = { workspace = true, optional = true } gdbstub = { workspace = true, optional = true } gdbstub_arch = { workspace = true, optional = true } igvm_defs = { workspace = true, features = ["unstable"] } @@ -71,7 +71,7 @@ verus_stub = { workspace = true } test.workspace = true [features] -attest = ["dep:aes", "dep:base64", "dep:cocoon-tpm-crypto", "dep:cocoon-tpm-tpm2-interface", "dep:cocoon-tpm-utils-common", "dep:kbs-types", "dep:libaproxy", "dep:serde", "dep:serde_json"] +attest = ["dep:aes-kw", "dep:cocoon-tpm-crypto", "dep:cocoon-tpm-tpm2-interface", "dep:cocoon-tpm-utils-common", "dep:concat-kdf", "dep:kbs-types", "dep:libaproxy", "dep:serde", "dep:serde_json"] default = [] enable-gdb = ["dep:gdbstub", "dep:gdbstub_arch"] diff --git a/kernel/src/attest.rs b/kernel/src/attest.rs index 3757d7ff3d..7197bff39a 100644 --- a/kernel/src/attest.rs +++ b/kernel/src/attest.rs @@ -14,15 +14,11 @@ use crate::{ serial::SerialPort, utils::vec::{try_to_vec, vec_sized}, }; -use aes::{cipher::BlockDecrypt, Aes256Dec}; -use aes_gcm::KeyInit; +use aes_gcm::{aead::generic_array::GenericArray, AeadInPlace, Aes256Gcm, KeyInit, Nonce}; +use aes_kw::{Kek, KekAes256}; use alloc::{string::ToString, vec::Vec}; -use base64::{ - prelude::{BASE64_STANDARD, BASE64_URL_SAFE}, - Engine, -}; use cocoon_tpm_crypto::{ - ecc::{curve::Curve, ecdh::ecdh_c_1e_1s_cdh_party_v_key_gen, EccKey}, + ecc::{curve::Curve, ecdh::ecdh_c_1_1_cdh_compute_z, EccKey}, rng::{self, HashDrbg, RngCore as _, X86RdSeedRng}, CryptoError, EmptyCryptoIoSlices, }; @@ -31,7 +27,6 @@ use cocoon_tpm_utils_common::{ alloc::try_alloc_zeroizing_vec, io_slices::{self, IoSlicesIterCommon as _}, }; -use core::cmp::min; use kbs_types::Tee; use libaproxy::*; use serde::Serialize; @@ -81,7 +76,7 @@ impl AttestationDriver<'_> { /// mechanism). fn negotiation(&mut self) -> Result { let request = NegotiationRequest { - version: "0.1.0".to_string(), // Only version supported at present. + version: (0, 1, 0), // Only version supported at present. tee: self.tee, }; @@ -104,13 +99,13 @@ impl AttestationDriver<'_> { .to_tpms_ecc_point(&curve.curve_ops().map_err(AttestationError::Crypto)?) .map_err(AttestationError::Crypto)?; - let evidence = evidence(&self.tee, hash(n, &pub_key)?)?; + let evidence = evidence(&self.tee, hash(&n, &pub_key)?)?; let req = AttestationRequest { - evidence: BASE64_URL_SAFE.encode(evidence), - key: (self.ecc.pub_key().get_curve_id(), &pub_key) - .try_into() - .map_err(|_| AttestationError::AttestationDeserialize)?, + tee: self.tee, + evidence, + challenge: n.challenge.clone(), + key: (self.ecc.pub_key().get_curve_id(), &pub_key).into(), }; self.write(req)?; @@ -123,45 +118,66 @@ impl AttestationDriver<'_> { return Err(AttestationError::Failed); } - let Some(ak) = response.pub_key else { + let Some(decryption) = response.decryption else { return Err(AttestationError::PublicKeyMissing)?; }; - let pub_key: TpmsEccPoint<'static> = ak.try_into().map_err(AttestationError::Crypto)?; - - let Some(ciphertext) = response.secret else { + let Some(mut secret) = response.secret else { return Err(AttestationError::SecretMissing); }; - self.decrypt(ciphertext, pub_key) + self.decrypt(&mut secret, decryption)?; + + Ok(secret) } - /// Decrypt a secret from the attestation server with the TEE private key. - fn decrypt( - &self, - ciphertext: Vec, - pub_key: TpmsEccPoint<'static>, - ) -> Result, AttestationError> { - let shared_secret = - ecdh_c_1e_1s_cdh_party_v_key_gen(TpmiAlgHash::Sha256, "", &self.ecc, &pub_key) - .map_err(AttestationError::Crypto)?; - - let aes = Aes256Dec::new_from_slice(&shared_secret[..]) - .map_err(|_| AttestationError::AesGenerate)?; - // Decrypt each 16-byte block of the ciphertext with the symmetric key. - let mut ptr = 0; - let len = ciphertext.len(); - let mut vec: Vec = Vec::new(); - while ptr < len { - let remain = min(16, len - ptr); - let mut arr: [u8; 16] = [0u8; 16]; - arr[..remain].copy_from_slice(&ciphertext[ptr..ptr + remain]); - aes.decrypt_block((&mut arr).into()); - vec.append(&mut try_to_vec(&arr).or(Err(AttestationError::VecAlloc))?); - ptr += remain; - } + /// Decrypt a secret from the attestation server with the TEE private key. Secrets are + /// encrypted with ECDH-ES+A256KW as described in RFC 7518, section 4.6.2. + fn decrypt(&self, secret: &mut [u8], decryption: AesGcmData) -> Result<(), AttestationError> { + let epk: TpmsEccPoint<'static> = decryption.epk.into(); + let z = ecdh_c_1_1_cdh_compute_z(&self.ecc, &epk).map_err(AttestationError::Crypto)?; + + let mut kdm = Vec::new(); + let alg_str = "ECDH-ES+A256KW".to_string(); + + kdm.extend_from_slice(&(alg_str.len() as u32).to_be_bytes()); + kdm.extend_from_slice(alg_str.as_bytes()); + kdm.extend_from_slice(&(0_u32).to_be_bytes()); + kdm.extend_from_slice(&(0_u32).to_be_bytes()); + kdm.extend_from_slice(&(256_u32).to_be_bytes()); + + let wrapping_key: KekAes256 = { + let mut buf: Vec = vec_sized(32).or(Err(AttestationError::VecAlloc))?; + + concat_kdf::derive_key_into::(&z, &kdm, &mut buf) + .map_err(AttestationError::KeyDerivation)?; + + let sized: [u8; 32] = buf + .try_into() + .or(Err(AttestationError::WrapKeyArrayConvert))?; + + Kek::new(&GenericArray::from(sized)) + }; + + let mut cek = + vec_sized(&decryption.wrapped_cek.len() - 8).or(Err(AttestationError::VecAlloc))?; - Ok(vec) + wrapping_key + .unwrap(&decryption.wrapped_cek, &mut cek) + .or(Err(AttestationError::CekUnwrap))?; + + let cipher = Aes256Gcm::new(GenericArray::from_slice(&cek)); + + cipher + .decrypt_in_place_detached( + Nonce::from_slice(&decryption.iv), + &decryption.aad, + secret, + GenericArray::from_slice(&decryption.tag), + ) + .map_err(AttestationError::SecretDecrypt)?; + + Ok(()) } /// Read attestation data from the serial port. @@ -208,8 +224,14 @@ pub enum AttestationError { AesGenerate, /// Error deserializing the attestation response from JSON bytes. AttestationDeserialize, + // Unable to unwrap Content Encryption Key (CEK). + CekUnwrap, + /// Unable to generate secure channel key. + Crypto(CryptoError), /// Guest has failed attestation. Failed, + // Unable to derive wrap key. + KeyDerivation(concat_kdf::Error), /// Error deserializing the negotiation response from JSON bytes. NegotiationDeserialize, /// Error serializing the negotiation request to JSON bytes. @@ -220,18 +242,18 @@ pub enum AttestationError { ProxyWrite, /// Attestation successful, but no public key found. PublicKeyMissing, - /// Unsupported TEE architecture. - UnsupportedTee, - /// Unable to generate secure channel key. - Crypto(CryptoError), /// Attestation successful, but unable to decrypt secret. - SecretDecrypt, + SecretDecrypt(aes_gcm::Error), /// Attestation successful, but no secret found. SecretMissing, /// Unable to fetch SEV-SNP attestation report. SnpGetReport, + /// Unsupported TEE architecture. + UnsupportedTee, /// Unable to allocate memory for Vec. VecAlloc, + // Unable to convert wrap key to 32 byte array. + WrapKeyArrayConvert, } impl From for SvsmError { @@ -268,7 +290,7 @@ fn sc_key_generate(curve: &Curve) -> Result { } /// Hash negotiation parameters and fetch TEE evidence. -fn evidence(tee: &Tee, hash: Vec) -> Result, AttestationError> { +fn evidence(tee: &Tee, hash: Vec) -> Result { let evidence = match tee { &Tee::Snp => { let mut user_data = [0u8; 64]; @@ -295,7 +317,13 @@ fn evidence(tee: &Tee, hash: Vec) -> Result, AttestationError> { // Get the attestation report as bytes for serialization in the // AttestationRequest. - try_to_vec(resp.report().as_bytes()).or(Err(AttestationError::VecAlloc))? + let report = + try_to_vec(resp.report().as_bytes()).or(Err(AttestationError::VecAlloc))?; + + AttestationEvidence::Snp { + report, + certs_buf: None, + } } // We check for supported TEE architectures in the AttestationDriver's constructor. _ => unreachable!(), @@ -307,19 +335,15 @@ fn evidence(tee: &Tee, hash: Vec) -> Result, AttestationError> { /// Hash the negotiation parameters from the attestation server for inclusion in the /// attestation evidence. fn hash( - n: NegotiationResponse, + n: &NegotiationResponse, pub_key: &TpmsEccPoint<'static>, ) -> Result, AttestationError> { let mut sha = Sha512::new(); for p in &n.params { match p { - NegotiationParam::Base64StdBytes(s) => { - let decoded = BASE64_STANDARD - .decode(s) - .map_err(|_| AttestationError::NegotiationDeserialize)?; - - sha.update(decoded); + NegotiationParam::Challenge => { + sha.update(&n.challenge); } #[allow(irrefutable_let_patterns)] NegotiationParam::EcPublicKeyBytes => { diff --git a/libaproxy/src/attestation.rs b/libaproxy/src/attestation.rs index c85eb32c21..3ab0991f54 100644 --- a/libaproxy/src/attestation.rs +++ b/libaproxy/src/attestation.rs @@ -6,93 +6,142 @@ // Author: Tyler Fanelli extern crate alloc; +use super::*; use alloc::{ string::{String, ToString}, vec::Vec, }; -use base64::prelude::*; -use cocoon_tpm_crypto::CryptoError; +use base64::{prelude::BASE64_URL_SAFE_NO_PAD, Engine}; use cocoon_tpm_tpm2_interface::{Tpm2bEccParameter, TpmBuffer, TpmEccCurve, TpmsEccPoint}; use core::convert::TryFrom; +use kbs_types::{Tee, TeePubKey}; use serde::{Deserialize, Serialize}; +type Result = core::result::Result; + /// The format of the public key that is used to encrypt secrets sent to SVSM upon successful /// attestation. /// /// Based on JSON Web Key /// See for examples: #[derive(Serialize, Deserialize, Debug)] -pub enum AttestationKey { - EC { - crv: String, - x_b64url: String, - y_b64url: String, - }, +pub struct EcP256PublicKey { + #[serde( + serialize_with = "serialize_base64", + deserialize_with = "deserialize_base64" + )] + pub x: Vec, + #[serde( + serialize_with = "serialize_base64", + deserialize_with = "deserialize_base64" + )] + pub y: Vec, } -impl TryFrom<(TpmEccCurve, &TpmsEccPoint<'static>)> for AttestationKey { - type Error = CryptoError; - - fn try_from(args: (TpmEccCurve, &TpmsEccPoint<'static>)) -> Result { - let x_b64url = BASE64_URL_SAFE.encode(&*args.1.x.buffer); - let y_b64url = BASE64_URL_SAFE.encode(&*args.1.y.buffer); - - let crv = match args.0 { - TpmEccCurve::NistP224 => "EC224", - TpmEccCurve::NistP256 => "EC256", - TpmEccCurve::NistP384 => "EC384", - TpmEccCurve::NistP521 => "EC521", - _ => return Err(CryptoError::InvalidParams), +impl From<(TpmEccCurve, &TpmsEccPoint<'static>)> for EcP256PublicKey { + fn from(args: (TpmEccCurve, &TpmsEccPoint<'static>)) -> Self { + Self { + x: args.1.x.buffer.to_vec(), + y: args.1.y.buffer.to_vec(), } - .to_string(); + } +} - Ok(AttestationKey::EC { - crv, - x_b64url, - y_b64url, - }) +impl From for TpmsEccPoint<'static> { + fn from(arg: EcP256PublicKey) -> Self { + TpmsEccPoint { + x: Tpm2bEccParameter { + buffer: TpmBuffer::Owned(arg.x), + }, + y: Tpm2bEccParameter { + buffer: TpmBuffer::Owned(arg.y), + }, + } } } -impl TryFrom for TpmsEccPoint<'static> { - type Error = CryptoError; - - fn try_from(arg: AttestationKey) -> Result { - match arg { - AttestationKey::EC { - crv: _, - x_b64url, - y_b64url, - } => { - let x_buf = BASE64_URL_SAFE - .decode(&x_b64url) - .map_err(|_| CryptoError::InvalidParams)?; - let y_buf = BASE64_URL_SAFE - .decode(&y_b64url) - .map_err(|_| CryptoError::InvalidParams)?; - - let point = TpmsEccPoint { - x: Tpm2bEccParameter { - buffer: TpmBuffer::Owned(x_buf), - }, - y: Tpm2bEccParameter { - buffer: TpmBuffer::Owned(y_buf), - }, - }; - - Ok(point) - } +impl From for TeePubKey { + fn from(arg: EcP256PublicKey) -> Self { + Self::EC { + alg: "ECDH-ES+A256KW".to_string(), + crv: "P-521".to_string(), + x: BASE64_URL_SAFE_NO_PAD.encode(arg.x), + y: BASE64_URL_SAFE_NO_PAD.encode(arg.y), } } } +impl TryFrom for EcP256PublicKey { + type Error = super::Error; + + fn try_from(arg: TeePubKey) -> Result { + let TeePubKey::EC { crv, alg, x, y } = arg else { + return Err(Error::InvalidKeyType); + }; + + if crv != "P-521" || alg != "ECDH-ES+A256KW" { + return Err(Error::InvalidKeyType); + }; + + let key = Self { + x: BASE64_URL_SAFE_NO_PAD + .decode(&x) + .map_err(Error::KeyParamDecode)?, + y: BASE64_URL_SAFE_NO_PAD + .decode(&y) + .map_err(Error::KeyParamDecode)?, + }; + + Ok(key) + } +} + /// The attestation request payload sent to the proxy from SVSM. #[derive(Serialize, Deserialize, Debug)] pub struct AttestationRequest { + /// TEE architecture. + pub tee: Tee, /// Attestation evidence generated by SVSM - pub evidence: String, + pub evidence: AttestationEvidence, + /// Challenge returned in negotiation response. + #[serde( + serialize_with = "serialize_base64", + deserialize_with = "deserialize_base64" + )] + pub challenge: Vec, /// Public key generated by SVSM to receive the secret - pub key: AttestationKey, + pub key: EcP256PublicKey, +} + +/// The attestation evidence based on the underlying TEE architecture. +#[derive(Serialize, Deserialize, Debug)] +pub enum AttestationEvidence { + /// SEV-SNP evidence. + Snp { + /// SEV-SNP attestation report. + #[serde( + serialize_with = "serialize_base64", + deserialize_with = "deserialize_base64" + )] + report: Vec, + /// Certificates that may be available from the host hypervisor. + #[serde( + skip_serializing_if = "Option::is_none", + default = "Option::default", + serialize_with = "serialize_base64_option", + deserialize_with = "deserialize_base64_option" + )] + certs_buf: Option>, + }, +} + +/// Token typically returned in successful attestations. +#[derive(Serialize, Deserialize, Debug)] +pub enum AttestationToken { + /// Token serialized to JSON (JWT). + Jwt(String), + /// Token serialized to CBOR (CWT). + Cwt(String), } /// Response from proxy to SVSM indicating the status of attestation as well as an optional secret @@ -102,7 +151,49 @@ pub struct AttestationResponse { /// Remote attestation result pub success: bool, /// Secret encrypted with the key generated by SVSM + #[serde( + skip_serializing_if = "Option::is_none", + default = "Option::default", + serialize_with = "serialize_base64_option", + deserialize_with = "deserialize_base64_option" + )] pub secret: Option>, /// Server's public key used for symmetric encryption/decryption. - pub pub_key: Option, + pub decryption: Option, + /// EAR or other token received from successful attestation. + pub token: Option, +} + +/// Data required for decryption with ECDH-ES+A256KW encryption. Described in RFC 7518, +/// section 4.6.2. +#[derive(Serialize, Deserialize, Debug)] +pub struct AesGcmData { + // Ephemeral public key. Required for ECDH handshake unwrapping the Content Encryption Key + // (CEK). + pub epk: EcP256PublicKey, + // Encrypted Content Encryption Key (CEK). + #[serde( + serialize_with = "serialize_base64", + deserialize_with = "deserialize_base64" + )] + pub wrapped_cek: Vec, + // Additional Authenticated Data (AAD). Used to authenticate the message, ensuring that it has + // not been tampered with. + #[serde( + serialize_with = "serialize_base64", + deserialize_with = "deserialize_base64" + )] + pub aad: Vec, + // Initialization vector. + #[serde( + serialize_with = "serialize_base64", + deserialize_with = "deserialize_base64" + )] + pub iv: Vec, + // Authentication tag. + #[serde( + serialize_with = "serialize_base64", + deserialize_with = "deserialize_base64" + )] + pub tag: Vec, } diff --git a/libaproxy/src/lib.rs b/libaproxy/src/lib.rs index 7cdcba00f0..f14c3f6efe 100644 --- a/libaproxy/src/lib.rs +++ b/libaproxy/src/lib.rs @@ -7,8 +7,72 @@ #![no_std] +extern crate alloc; + mod attestation; mod negotiation; pub use attestation::*; pub use negotiation::*; + +use alloc::{string::String, vec::Vec}; +use base64::{prelude::BASE64_STANDARD, Engine}; +use serde::Deserialize; + +#[derive(Debug)] +pub enum Error { + InvalidKeyType, + KeyParamDecode(base64::DecodeError), + InvalidParams, +} + +fn serialize_base64(sub: &Vec, serializer: S) -> core::result::Result +where + S: serde::Serializer, +{ + let encoded = BASE64_STANDARD.encode(sub); + serializer.serialize_str(&encoded) +} + +fn deserialize_base64<'de, D>(deserializer: D) -> core::result::Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let encoded = String::deserialize(deserializer)?; + let decoded = BASE64_STANDARD + .decode(encoded) + .map_err(serde::de::Error::custom)?; + + Ok(decoded) +} + +fn serialize_base64_option( + sub: &Option>, + serializer: S, +) -> core::result::Result +where + S: serde::Serializer, +{ + match sub { + Some(value) => { + let encoded = BASE64_STANDARD.encode(value); + serializer.serialize_str(&encoded) + } + None => serializer.serialize_none(), + } +} + +fn deserialize_base64_option<'de, D>( + deserializer: D, +) -> core::result::Result>, D::Error> +where + D: serde::Deserializer<'de>, +{ + let encoded = String::deserialize(deserializer)?; + + let decoded = BASE64_STANDARD + .decode(encoded) + .map_err(serde::de::Error::custom)?; + + Ok(Some(decoded)) +} diff --git a/libaproxy/src/negotiation.rs b/libaproxy/src/negotiation.rs index ef34ecc5a5..8bd18d462e 100644 --- a/libaproxy/src/negotiation.rs +++ b/libaproxy/src/negotiation.rs @@ -6,29 +6,37 @@ // Author: Tyler Fanelli extern crate alloc; -use alloc::{string::String, vec::Vec}; + +use super::*; +use alloc::vec::Vec; use serde::{Deserialize, Serialize}; /// The initial payload sent from SVSM to the attestation proxy. The version indicates the version /// of the SVSM attestation protocol to use. #[derive(Serialize, Deserialize, Debug)] pub struct NegotiationRequest { - pub version: String, + /// Version of the attestation protocol, represented as semver (MAJOR.MINOR.PATCH). + pub version: (u32, u32, u32), pub tee: kbs_types::Tee, } /// A parameter that must be hashed into the negotiation hash. #[derive(Serialize, Deserialize, Debug)] pub enum NegotiationParam { + /// Hash the challenge returned from attestation server. + Challenge, /// Hash the EC public key's `Elliptic-Curve-Point-to-Octet-String` encoding. EcPublicKeyBytes, - /// A base64-encoded byte array. This could represent a nonce or any other data the - /// attestation server would like to embed in TEE evidence. - Base64StdBytes(String), } #[derive(Serialize, Deserialize, Debug)] pub struct NegotiationResponse { + /// Challenge returned from the attestation server to verify freshness of attestation evidence. + #[serde( + serialize_with = "serialize_base64", + deserialize_with = "deserialize_base64" + )] + pub challenge: Vec, /// Parameters to be hashed in the specific order defined by the array pub params: Vec, }