Repository: virtee/snpguest
Pull request #89: Updating to version 6 of library and fixing attestation
Author: login: DGonzalezVillal
Created: 2025-03-21T19:21:50Z | Merged: 2025-04-24T15:13:56Z

This update bumps the dependency to version 6 of the SEV libarary.

Besides fixing the code compatibility, we changed the way certificate fetching is done.

Now the user is expected to provide a V3 attestation report, with chich we can tell for what processor model we will be getting the certificates from. If the user doesn't have a V3 report in the firmware, or wants to get certs for a different proc model, they can still use the --processor_model flag.

The verification also add a --processor_model flag in case they need to attest a V2 of the report.


Diff:
diff --git a/Cargo.lock b/Cargo.lock
index d4d7967..59b0eae 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -67,19 +67,20 @@ dependencies = [
 
 [[package]]
 name = "anstyle-wincon"
-version = "3.0.6"
+version = "3.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
 dependencies = [
  "anstyle",
+ "once_cell",
  "windows-sys 0.59.0",
 ]
 
 [[package]]
 name = "anyhow"
-version = "1.0.93"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
+checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
 
 [[package]]
 name = "asn1-rs"
@@ -182,15 +183,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bitflags"
-version = "2.6.0"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
 
 [[package]]
 name = "bumpalo"
-version = "3.16.0"
+version = "3.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
 
 [[package]]
 name = "byteorder"
@@ -200,15 +201,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "bytes"
-version = "1.8.0"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da"
+checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
 
 [[package]]
 name = "cc"
-version = "1.2.1"
+version = "1.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
+checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229"
 dependencies = [
  "shlex",
 ]
@@ -221,9 +222,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "clap"
-version = "4.5.21"
+version = "4.5.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
+checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -231,18 +232,18 @@ dependencies = [
 
 [[package]]
 name = "clap-num"
-version = "1.1.1"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e063d263364859dc54fb064cedb7c122740cd4733644b14b176c097f51e8ab7"
+checksum = "822c4000301ac390e65995c62207501e3ef800a1fc441df913a5e8e4dc374816"
 dependencies = [
  "num-traits",
 ]
 
 [[package]]
 name = "clap_builder"
-version = "4.5.21"
+version = "4.5.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
+checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
 dependencies = [
  "anstream",
  "anstyle",
@@ -252,9 +253,9 @@ dependencies = [
 
 [[package]]
 name = "clap_derive"
-version = "4.5.18"
+version = "4.5.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
+checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -264,9 +265,9 @@ dependencies = [
 
 [[package]]
 name = "clap_lex"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
+checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
 
 [[package]]
 name = "codicon"
@@ -304,9 +305,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
 
 [[package]]
 name = "data-encoding"
-version = "2.6.0"
+version = "2.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
+checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f"
 
 [[package]]
 name = "der-parser"
@@ -374,18 +375,18 @@ dependencies = [
 
 [[package]]
 name = "enumflags2"
-version = "0.7.10"
+version = "0.7.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d"
+checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147"
 dependencies = [
  "enumflags2_derive",
 ]
 
 [[package]]
 name = "enumflags2_derive"
-version = "0.7.10"
+version = "0.7.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
+checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -413,19 +414,19 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
 
 [[package]]
 name = "errno"
-version = "0.3.9"
+version = "0.3.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
 dependencies = [
  "libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
 name = "fastrand"
-version = "2.2.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
 
 [[package]]
 name = "fnv"
@@ -513,7 +514,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.13.3+wasi-0.2.2",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -553,12 +566,6 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 
-[[package]]
-name = "hermit-abi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
-
 [[package]]
 name = "hermit-abi"
 version = "0.4.0"
@@ -601,9 +608,9 @@ dependencies = [
 
 [[package]]
 name = "httparse"
-version = "1.9.5"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
+checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a"
 
 [[package]]
 name = "httpdate"
@@ -619,9 +626,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
 [[package]]
 name = "hyper"
-version = "0.14.31"
+version = "0.14.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85"
+checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -795,9 +802,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "2.6.0"
+version = "2.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
+checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -811,19 +818,19 @@ checksum = "d8972d5be69940353d5347a1344cb375d9b457d6809b428b05bb1ca2fb9ce007"
 
 [[package]]
 name = "ipnet"
-version = "2.10.1"
+version = "2.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
+checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
 
 [[package]]
 name = "is-terminal"
-version = "0.4.13"
+version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
+checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37"
 dependencies = [
- "hermit-abi 0.4.0",
+ "hermit-abi",
  "libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -840,10 +847,11 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
 
 [[package]]
 name = "js-sys"
-version = "0.3.72"
+version = "0.3.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
 dependencies = [
+ "once_cell",
  "wasm-bindgen",
 ]
 
@@ -855,9 +863,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "libc"
-version = "0.2.166"
+version = "0.2.169"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36"
+checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
 
 [[package]]
 name = "libredox"
@@ -865,15 +873,15 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
 dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
  "libc",
 ]
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
 
 [[package]]
 name = "litemap"
@@ -883,9 +891,9 @@ checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
 
 [[package]]
 name = "log"
-version = "0.4.22"
+version = "0.4.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
 
 [[package]]
 name = "mbox"
@@ -926,22 +934,21 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 
 [[package]]
 name = "miniz_oxide"
-version = "0.8.0"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
+checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
 dependencies = [
  "adler2",
 ]
 
 [[package]]
 name = "mio"
-version = "1.0.2"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
+checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
 dependencies = [
- "hermit-abi 0.3.9",
  "libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
  "windows-sys 0.52.0",
 ]
 
@@ -953,9 +960,9 @@ checksum = "15a014208ef068fd9eed02eceb063ecba151d9922de4f8b4bb3703ff3d2a3eaa"
 
 [[package]]
 name = "native-tls"
-version = "0.2.12"
+version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
+checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c"
 dependencies = [
  "libc",
  "log",
@@ -1038,9 +1045,9 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.36.5"
+version = "0.36.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
+checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
 dependencies = [
  "memchr",
 ]
@@ -1071,11 +1078,11 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
 
 [[package]]
 name = "openssl"
-version = "0.10.68"
+version = "0.10.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
+checksum = "f5e534d133a060a3c19daec1eb3e98ec6f4685978834f2dbadfe2ec215bab64e"
 dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
  "cfg-if",
  "foreign-types",
  "libc",
@@ -1097,9 +1104,9 @@ dependencies = [
 
 [[package]]
 name = "openssl-probe"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
 
 [[package]]
 name = "openssl-src"
@@ -1172,9 +1179,9 @@ dependencies = [
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.15"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
 
 [[package]]
 name = "pin-utils"
@@ -1205,18 +1212,18 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.92"
+version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.37"
+version = "1.0.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
 dependencies = [
  "proc-macro2",
 ]
@@ -1248,7 +1255,7 @@ version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
 ]
 
 [[package]]
@@ -1266,7 +1273,7 @@ version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
 dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
  "libredox",
  "thiserror",
 ]
@@ -1348,7 +1355,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
 dependencies = [
  "cc",
  "cfg-if",
- "getrandom",
+ "getrandom 0.2.15",
  "libc",
  "spin",
  "untrusted",
@@ -1372,15 +1379,15 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.41"
+version = "0.38.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
+checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
 dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
  "errno",
  "libc",
  "linux-raw-sys",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -1392,11 +1399,17 @@ dependencies = [
  "base64 0.21.7",
 ]
 
+[[package]]
+name = "rustversion"
+version = "1.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
+
 [[package]]
 name = "ryu"
-version = "1.0.18"
+version = "1.0.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
 
 [[package]]
 name = "schannel"
@@ -1413,7 +1426,7 @@ version = "2.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
 dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
  "core-foundation",
  "core-foundation-sys",
  "libc",
@@ -1422,9 +1435,9 @@ dependencies = [
 
 [[package]]
 name = "security-framework-sys"
-version = "2.12.1"
+version = "2.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2"
+checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -1432,9 +1445,9 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.215"
+version = "1.0.217"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
+checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
 dependencies = [
  "serde_derive",
 ]
@@ -1459,9 +1472,9 @@ dependencies = [
 
 [[package]]
 name = "serde_derive"
-version = "1.0.215"
+version = "1.0.217"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
+checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1470,9 +1483,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.133"
+version = "1.0.138"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
+checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
 dependencies = [
  "itoa",
  "memchr",
@@ -1494,9 +1507,9 @@ dependencies = [
 
 [[package]]
 name = "sev"
-version = "5.0.0"
+version = "6.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b06afe5192a43814047ea0072f4935f830a1de3c8cb43b56c90ae6918468b94d"
+checksum = "20ac277517d8fffdf3c41096323ed705b3a7c75e397129c072fb448339839d0f"
 dependencies = [
  "base64 0.22.1",
  "bincode",
@@ -1566,9 +1579,9 @@ dependencies = [
 
 [[package]]
 name = "socket2"
-version = "0.5.7"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
+checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
 dependencies = [
  "libc",
  "windows-sys 0.52.0",
@@ -1600,9 +1613,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.89"
+version = "2.0.96"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e"
+checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1655,12 +1668,13 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
 
 [[package]]
 name = "tempfile"
-version = "3.14.0"
+version = "3.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
+checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
 dependencies = [
  "cfg-if",
  "fastrand",
+ "getrandom 0.3.1",
  "once_cell",
  "rustix",
  "windows-sys 0.59.0",
@@ -1697,9 +1711,9 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.3.36"
+version = "0.3.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
+checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
 dependencies = [
  "deranged",
  "itoa",
@@ -1718,9 +1732,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
 
 [[package]]
 name = "time-macros"
-version = "0.2.18"
+version = "0.2.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
+checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de"
 dependencies = [
  "num-conv",
  "time-core",
@@ -1738,9 +1752,9 @@ dependencies = [
 
 [[package]]
 name = "tokio"
-version = "1.41.1"
+version = "1.43.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33"
+checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
 dependencies = [
  "backtrace",
  "bytes",
@@ -1763,9 +1777,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-util"
-version = "0.7.12"
+version = "0.7.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"
+checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
 dependencies = [
  "bytes",
  "futures-core",
@@ -1782,9 +1796,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
 
 [[package]]
 name = "tracing"
-version = "0.1.40"
+version = "0.1.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
 dependencies = [
  "pin-project-lite",
  "tracing-core",
@@ -1807,13 +1821,13 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
 
 [[package]]
 name = "tss-esapi"
-version = "7.5.1"
+version = "7.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9ba6594ded739cb539f8ffcd3713f6c21d4525c47314bbc6de15c0cd251aedf"
+checksum = "78ea9ccde878b029392ac97b5be1f470173d06ea41d18ad0bb3c92794c16a0f2"
 dependencies = [
  "bitfield 0.14.0",
  "enumflags2",
- "getrandom",
+ "getrandom 0.2.15",
  "hostname-validator",
  "log",
  "mbox",
@@ -1840,9 +1854,9 @@ dependencies = [
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.14"
+version = "1.0.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
 
 [[package]]
 name = "untrusted"
@@ -1881,9 +1895,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 
 [[package]]
 name = "uuid"
-version = "1.11.0"
+version = "1.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
+checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
 dependencies = [
  "serde",
 ]
@@ -1909,26 +1923,35 @@ version = "0.11.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
+[[package]]
+name = "wasi"
+version = "0.13.3+wasi-0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.95"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
 dependencies = [
  "cfg-if",
  "once_cell",
+ "rustversion",
  "wasm-bindgen-macro",
 ]
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.95"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
 dependencies = [
  "bumpalo",
  "log",
- "once_cell",
  "proc-macro2",
  "quote",
  "syn",
@@ -1937,21 +1960,22 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.45"
+version = "0.4.50"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b"
+checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
 dependencies = [
  "cfg-if",
  "js-sys",
+ "once_cell",
  "wasm-bindgen",
  "web-sys",
 ]
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.95"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -1959,9 +1983,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.95"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1972,15 +1996,18 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.95"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
 
 [[package]]
 name = "web-sys"
-version = "0.3.72"
+version = "0.3.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112"
+checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -2153,6 +2180,15 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
+[[package]]
+name = "wit-bindgen-rt"
+version = "0.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+dependencies = [
+ "bitflags 2.8.0",
+]
+
 [[package]]
 name = "write16"
 version = "1.0.0"
diff --git a/Cargo.toml b/Cargo.toml
index 8fef511..4bd7f7f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,7 +22,7 @@ hyperv = ["tss-esapi"]
 clap = { version = "4.5", features = [ "derive" ] }
 env_logger = "0.10.0"
 anyhow = "1.0.69"
-sev = { version = "5.0.0", default-features = false, features = ['openssl','snp']}
+sev = { version = "6.0.0", default-features = false, features = ['openssl','snp']}
 nix = "^0.23"
 serde = { version = "1.0", features = ["derive"] }
 bincode = "^1.2.1"
diff --git a/docs/snpguest.1.adoc b/docs/snpguest.1.adoc
index 5a14e1a..fc1ac65 100644
--- a/docs/snpguest.1.adoc
+++ b/docs/snpguest.1.adoc
@@ -60,32 +60,38 @@ COMMANDS
     -h, --help  show a help message
 
 *snpguest fetch ca*::
-    usage: snpguest fetch ca $ENCODING $PROCESSOR_MODEL $CERTS_DIR
+    usage: snpguest fetch ca $ENCODING $CERTS_DIR $PROCESSOR_MODEL [-r, --report] $ATT_REPORT_PATH [-E --endorser] $ENDORSEMENT
 
     Requests the certificate authority chain (ARK & ASK) from the KDS.
-    The user needs to specify the certificate encoding they would like store the certs in [PEM | DER].
-    Currently only PEM and DER encondings are supported.
-    Both of the certs will be in the same encoding.
-    The user must specify their host processor model [Milan | Genoa].
+    The user needs to specify the certificate encoding they would like to store the certs in [PEM | DER].
+    Currently, only PEM and DER encodings are supported.
+    Both certificates will be in the same encoding.
     The user needs to provide the path to the directory where the certs will be stored.
     If the certificates already exist in the provided directory, they will be overwritten.
+    The user must either pass a V3 attestation report or manually specify the host processor model using the --processor_model flag.
+    This ensures the correct CA certificates for attestation are retrieved from the KDS. [Milan | Genoa | Bergamo | Siena | Turin]
+    Lastly, the user may specify the endorser they would like the CA chain for using the --endorser flag. [VCEK | VLEK]
+    It will default to VCEK.
 
     options:
     -h, --help show a help message
+    -p, -processor_model Specify processor model to retrieve the CA certificates for.
+    -e, --enodorse  Specify the endorser type to get the Ca certificates for. (defaults to: VCEK)
 
 *snpguest fetch vcek*::
-    usage: snpguest fetch vcek $ENCODING $PROCESSOR_MODEL $CERTS_DIR $ATT_REPORT_PATH
+    usage: snpguest fetch vcek $ENCODING $CERTS_DIR $ATT_REPORT_PATH [-p, --processor_model] $PROCESSOR_MODEL
 
     Requests the VCEK certificate from the KDS.
     The user needs to specify the certificate encoding they would like store the cert in [PEM | DER].
     Currently only PEM and DER encondings are supported.
-    The user must specify their host processor model [Milan | Genoa].
     The user needs to provide the path to the directory where the VCEK will be stored.
     If the certificate already exists in the provided directory, it will be overwritten.
-    The user also needs to provide the path to a stored attestation report that will be used to request the VCEK.
+    The user must either pass a V3 attestation report or manually specify the host processor model using the --processor_model flag.
+    This ensures the correct VCEK certificate for attestation is retrieved from the KDS. [Milan | Genoa | Bergamo | Siena | Turin]
 
     options:
     -h, --help show a help message
+    -p, --processor_model Specify processor model to retrieve the VCEK certificates for.
 
 *snpguest guest verify certs*::
     usage: snpguest verify certs $CERTS_DIR
@@ -98,17 +104,22 @@ COMMANDS
     -h, --help show a help message
 
 *snpguest verify attestation*::
-    usage: snpguest verify attestation $CERTS_DIR $ATT_REPORT_PATH [-t, --tcb] [-s, --signature]
+    usage: snpguest verify attestation $CERTS_DIR $ATT_REPORT_PATH [-p, --processor_model] $PROCESSOR_MODEL [-t, --tcb] [-s, --signature]
 
-    Verifies the contents of the Attestation Report using the VCEK certificate.
-    The user needs to provide the path to the directory containing the VCEK certificate.
+    Verifies the contents of the Attestation Report using a VEK certificate.
+    The user needs to provide the path to the directory containing the VEK certificate.
+    The tool will automatically recognize whether it's a VLEK or VCEK.
+    If both a VLEK and a VCEK are in the directory, then the VCEK will be used.
     The user also needs to provide the path to a stored attestation report to be verified.
-    Error will be raised if the attestation verification fails at any point.
+    If the report is not version 3 or newer, then the user can specify the cpu model to verify using the --processor_model flag.
+    If no processor model is passed, and the report is a version 2, then the verification will be treated as a Genoa or older verification.
+    An error will be raised if the attestation verification fails at any point.
     The user can use the [-t, --tcb] flag to only validate the tcb contents of the report.
     The user can use the [-s, --signature] flag to only validate the report signature.
 
     options:
     -h, --help show a help message
+    -p, --processor_model Specify the processor model to use for verification
     -t, --tcb verify the tcb section of the report only
     -s, --signature verify the signature of the report only
 
diff --git a/src/fetch.rs b/src/fetch.rs
index 9b10c7b..5a333ee 100644
--- a/src/fetch.rs
+++ b/src/fetch.rs
@@ -9,7 +9,10 @@ use std::{fs, path::PathBuf, str::FromStr};
 
 use reqwest::blocking::{get, Response};
 
-use sev::{certs::snp::ca::Chain, firmware::host::CertType};
+use sev::{
+    certs::snp::ca::Chain,
+    firmware::{guest::AttestationReport, host::CertType},
+};
 
 use certs::{write_cert, CertFormat};
 
@@ -51,7 +54,7 @@ impl FromStr for Endorsement {
         }
     }
 }
-#[derive(ValueEnum, Debug, Clone)]
+#[derive(ValueEnum, Debug, Clone, PartialEq, Eq)]
 pub enum ProcType {
     /// 3rd Gen AMD EPYC Processor (Standard)
     Milan,
@@ -105,6 +108,46 @@ impl fmt::Display for ProcType {
     }
 }
 
+pub fn get_processor_model(att_report: AttestationReport) -> Result<ProcType> {
+    if att_report.version < 3 {
+        if att_report.key_info.mask_chip_key() {
+            return Err(anyhow::anyhow!(
+                "Attestation report version is too and mask chip key is set to 1, there is no way of getting the cpu model."
+            ));
+        } else {
+            let chip_id = *att_report.chip_id;
+            if chip_id[8..64] == [0; 56] {
+                return Ok(ProcType::Turin);
+            } else {
+                return Err(anyhow::anyhow!(
+                    "Attestation report could be either Milan or Genoa."
+                ));
+            }
+        }
+    }
+
+    let cpu_fam = att_report
+        .cpuid_fam_id
+        .ok_or_else(|| anyhow::anyhow!("Attestation report version 3+ is missing CPU family ID"))?;
+
+    let cpu_mod = att_report
+        .cpuid_mod_id
+        .ok_or_else(|| anyhow::anyhow!("Attestation report version 3+ is missing CPU model ID"))?;
+
+    match cpu_fam {
+        0x19 => match cpu_mod {
+            0x0..=0xF => Ok(ProcType::Milan),
+            0x10..=0x1F | 0xA0..0xAF => Ok(ProcType::Genoa),
+            _ => Err(anyhow::anyhow!("Processor model not supported")),
+        },
+        0x1A => match cpu_mod {
+            0x0..=0x11 => Ok(ProcType::Turin),
+            _ => Err(anyhow::anyhow!("Processor model not supported")),
+        },
+        _ => Err(anyhow::anyhow!("Processor family not supported")),
+    }
+}
+
 pub fn cmd(cmd: FetchCmd) -> Result<()> {
     match cmd {
         FetchCmd::CA(args) => cert_authority::fetch_ca(args),
@@ -122,14 +165,29 @@ mod cert_authority {
         #[arg(value_name = "encoding", required = true, ignore_case = true)]
         pub encoding: CertFormat,
 
-        /// Specify the processor model for the certificate chain.
-        #[arg(value_name = "processor-model", required = true, ignore_case = true)]
-        pub processor_model: ProcType,
-
         /// Directory to store the certificates in.
         #[arg(value_name = "certs-dir", required = true)]
         pub certs_dir: PathBuf,
 
+        /// Specify the processor model for the desired certificate chain.
+        #[arg(
+            value_name = "processor-model",
+            required_unless_present = "att_report",
+            conflicts_with = "att_report",
+            ignore_case = true
+        )]
+        pub processor_model: Option<ProcType>,
+
+        /// Attestation Report to get processor model from (V3 of report needed).
+        #[arg(
+            short = 'r',
+            long = "report",
+            value_name = "att-report",
+            conflicts_with = "processor_model",
+            ignore_case = true
+        )]
+        pub att_report: Option<PathBuf>,
+
         /// Specify which endorsement certificate chain to pull, either VCEK or VLEK.
         #[arg(short, long, value_name = "endorser", default_value_t = Endorsement::Vcek, ignore_case = true)]
         pub endorser: Endorsement,
@@ -170,8 +228,17 @@ mod cert_authority {
 
     // Fetch the ca from the kds and write it into the certs directory
     pub fn fetch_ca(args: Args) -> Result<()> {
+        let proc_model = if let Some(processor_model) = args.processor_model {
+            processor_model
+        } else if let Some(att_report) = args.att_report {
+            let report =
+                report::read_report(att_report).context("Could not open attestation report")?;
+            get_processor_model(report)?
+        } else {
+            return Err(anyhow::anyhow!("Attestation report is missing or invalid, or the user did not specify a processor model"));
+        };
         // Get certs from kds
-        let certificates = request_ca_kds(args.processor_model, &args.endorser)?;
+        let certificates = request_ca_kds(proc_model, &args.endorser)?;
 
         // Create certs directory if missing
         if !args.certs_dir.exists() {
@@ -201,6 +268,7 @@ mod cert_authority {
 }
 
 mod vcek {
+    use asn1_rs::nom::AsBytes;
     use reqwest::StatusCode;
 
     use super::*;
@@ -211,17 +279,17 @@ mod vcek {
         #[arg(value_name = "encoding", required = true, ignore_case = true)]
         pub encoding: CertFormat,
 
-        /// Specify the processor model for the certificate chain.
-        #[arg(value_name = "processor-model", required = true, ignore_case = true)]
-        pub processor_model: ProcType,
-
         /// Directory to store the certificates in.
         #[arg(value_name = "certs-dir", required = true)]
         pub certs_dir: PathBuf,
 
         /// Path to attestation report to use to request VCEK.
         #[arg(value_name = "att-report-path", required = true)]
-        pub att_report_path: PathBuf,
+        pub att_report: PathBuf,
+
+        /// Specify the processor model for the desired vcek.
+        #[arg(short, long, value_name = "processor-model", ignore_case = true)]
+        pub processor_model: Option<ProcType>,
     }
 
     // Function to request vcek from KDS. Return vcek in der format.
@@ -240,23 +308,52 @@ mod vcek {
             report::read_report(att_report_path).context("Could not open attestation report")?
         };
 
-        let hw_id: String = match processor_model {
-            ProcType::Turin => {
-                let shorter_bytes: &[u8] = &att_report.chip_id[0..8];
-                hex::encode(shorter_bytes)
+        // Get hardware id
+        let hw_id: String = if att_report.chip_id.as_bytes() != [0; 64] {
+            match processor_model {
+                ProcType::Turin => {
+                    let shorter_bytes: &[u8] = &att_report.chip_id[0..8];
+                    hex::encode(shorter_bytes)
+                }
+                _ => hex::encode(att_report.chip_id),
             }
-            _ => hex::encode(att_report.chip_id),
+        } else {
+            return Err(anyhow::anyhow!(
+                "Hardware ID is 0s on attestation report. Confirm that MASK_CHIP_ID is set to 0."
+            ));
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
+                let fmc = if let Some(fmc) = att_report.reported_tcb.fmc {
+                    fmc
+                } else {
+                    return Err(anyhow::anyhow!("A Turin processor must have a fmc value"));
+                };
+                format!(
+                    "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
+                    {hw_id}?fmcSPL={:02}&blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
+                    processor_model.to_kds_url(),
+                    fmc,
+                    att_report.reported_tcb.bootloader,
+                    att_report.reported_tcb.tee,
+                    att_report.reported_tcb.snp,
+                    att_report.reported_tcb.microcode
+                )
+            }
+            _ => {
+                format!(
+                    "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
+                    {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
+                    processor_model.to_kds_url(),
+                    att_report.reported_tcb.bootloader,
+                    att_report.reported_tcb.tee,
+                    att_report.reported_tcb.snp,
+                    att_report.reported_tcb.microcode
+                )
+            }
+        };
 
         // VCEK in DER format
         let vcek_rsp: Response = get(vcek_url).context("Unable to send request for VCEK")?;
@@ -273,8 +370,16 @@ mod vcek {
 
     // Function to request vcek from kds and write it into file
     pub fn fetch_vcek(args: Args) -> Result<()> {
+        let proc_model = if let Some(proc_model) = args.processor_model {
+            proc_model
+        } else {
+            let att_report = report::read_report(args.att_report.clone())
+                .context("Could not open attestation report")?;
+            get_processor_model(att_report)?
+        };
+
         // Request vcek
-        let vcek = request_vcek_kds(args.processor_model, args.att_report_path)?;
+        let vcek = request_vcek_kds(proc_model, args.att_report)?;
 
         if !args.certs_dir.exists() {
             fs::create_dir(&args.certs_dir).context("Could not create certs folder")?;
@@ -293,7 +398,8 @@ mod vcek {
 }
 #[cfg(test)]
 mod tests {
-    use super::ProcType;
+    use super::*;
+    use sev::firmware::guest::KeyInfo;
 
     #[test]
     fn test_kds_prod_name_milan_base() {
@@ -307,4 +413,87 @@ mod tests {
         assert_eq!(ProcType::Siena.to_kds_url(), ProcType::Genoa.to_string());
         assert_eq!(ProcType::Bergamo.to_kds_url(), ProcType::Genoa.to_string());
     }
+
+    #[test]
+    fn test_get_processor_model_milan() {
+        let att_report = AttestationReport {
+            version: 3,
+            cpuid_fam_id: Some(0x19),
+            cpuid_mod_id: Some(0x0),
+            ..Default::default()
+        };
+        let proc_model = get_processor_model(att_report).unwrap();
+        assert_eq!(proc_model, ProcType::Milan);
+    }
+
+    #[test]
+    fn test_get_processor_model_genoa() {
+        let att_report = AttestationReport {
+            version: 3,
+            cpuid_fam_id: Some(0x19),
+            cpuid_mod_id: Some(0x10),
+            ..Default::default()
+        };
+        let proc_model = get_processor_model(att_report).unwrap();
+        assert_eq!(proc_model, ProcType::Genoa);
+    }
+
+    #[test]
+    fn test_get_processor_model_turin() {
+        let att_report = AttestationReport {
+            version: 3,
+            cpuid_fam_id: Some(0x1A),
+            cpuid_mod_id: Some(0x0),
+            ..Default::default()
+        };
+        let proc_model = get_processor_model(att_report).unwrap();
+        assert_eq!(proc_model, ProcType::Turin);
+    }
+
+    #[test]
+    fn test_get_processor_model_unsupported_family() {
+        let att_report = AttestationReport {
+            version: 3,
+            cpuid_fam_id: Some(0x1B),
+            cpuid_mod_id: Some(0x0),
+            ..Default::default()
+        };
+        let result = get_processor_model(att_report);
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn test_get_processor_model_unsupported_model() {
+        let att_report = AttestationReport {
+            version: 3,
+            cpuid_fam_id: Some(0x19),
+            cpuid_mod_id: Some(0x20),
+            ..Default::default()
+        };
+        let result = get_processor_model(att_report);
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn test_get_processor_model_version_too_low() {
+        let att_report = AttestationReport {
+            version: 2,
+            chip_id: [1; 64].try_into().unwrap(),
+            ..Default::default()
+        };
+        let result = get_processor_model(att_report);
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn test_get_processor_model_mask_chip_key_set() {
+        let key_info = KeyInfo(0b10);
+        let att_report = AttestationReport {
+            version: 2,
+            key_info,
+            ..Default::default()
+        };
+        let result = get_processor_model(att_report);
+        assert!(result.is_err());
+    }
 }
diff --git a/src/report.rs b/src/report.rs
index 4531b46..09e1c0d 100644
--- a/src/report.rs
+++ b/src/report.rs
@@ -15,10 +15,15 @@ use sev::firmware::guest::{AttestationReport, Firmware};
 
 // Read a bin-formatted attestation report.
 pub fn read_report(att_report_path: PathBuf) -> Result<AttestationReport, anyhow::Error> {
-    let attestation_file = fs::File::open(att_report_path)?;
+    let mut attestation_file = fs::File::open(att_report_path)?;
 
-    let attestation_report = bincode::deserialize_from(attestation_file)
-        .context("Could not parse attestation report.")?;
+    let mut report_bytes = Vec::new();
+    attestation_file
+        .read_to_end(&mut report_bytes)
+        .context("Failed to read the report bytes.")?;
+
+    let attestation_report = AttestationReport::from_bytes(&report_bytes)
+        .context("Failed to build report from the raw bytes. Report could be malformed.")?;
 
     Ok(attestation_report)
 }
@@ -91,8 +96,11 @@ fn request_hardware_report(
 #[cfg(not(feature = "hyperv"))]
 fn request_hardware_report(data: Option<[u8; 64]>, vmpl: Option<u32>) -> Result<AttestationReport> {
     let mut fw = Firmware::open().context("unable to open /dev/sev-guest")?;
-    fw.get_report(None, data, vmpl)
-        .context("unable to fetch attestation report")
+    Ok(AttestationReport::from_bytes(
+        fw.get_report(None, data, vmpl)
+            .context("unable to fetch attestation report")?
+            .as_slice(),
+    )?)
 }
 
 // Request attestation report and write it into a file
@@ -126,8 +134,7 @@ pub fn get_report(args: ReportArgs, hv: bool) -> Result<()> {
         .write(true)
         .open(&args.att_report_path)?;
 
-    bincode::serialize_into(&mut file, &report)
-        .context("Could not serialize attestation report into file.")?;
+    report.write_bytes(&mut file)?;
 
     /*
      * Write reports report data (only for --random or --platform).
@@ -150,7 +157,8 @@ fn reqdata_write(name: PathBuf, report: &AttestationReport) -> Result<()> {
         .open(name)
         .context("unable to create or write to request data file")?;
 
-    write_hex(&mut file, &report.report_data).context("unable to write report data to REQUEST_FILE")
+    write_hex(&mut file, report.report_data.as_slice())
+        .context("unable to write report data to REQUEST_FILE")
 }
 
 pub fn write_hex(file: &mut File, data: &[u8]) -> Result<()> {
diff --git a/src/verify.rs b/src/verify.rs
index 91f47a5..0d34ce3 100644
--- a/src/verify.rs
+++ b/src/verify.rs
@@ -5,6 +5,8 @@ use super::*;
 
 use certs::{convert_path_to_cert, CertPaths};
 
+use fetch::{get_processor_model, ProcType};
+
 use std::{
     io::ErrorKind,
     path::{Path, PathBuf},
@@ -160,6 +162,7 @@ mod attestation {
         Snp,
         Ucode,
         HwId,
+        Fmc,
     }
 
     // OID extensions for the VCEK, will be used to verify attestation report
@@ -171,6 +174,7 @@ mod attestation {
                 SnpOid::Snp => oid!(1.3.6 .1 .4 .1 .3704 .1 .3 .3),
                 SnpOid::Ucode => oid!(1.3.6 .1 .4 .1 .3704 .1 .3 .8),
                 SnpOid::HwId => oid!(1.3.6 .1 .4 .1 .3704 .1 .4),
+                SnpOid::Fmc => oid!(1.3.6 .1 .4 .1 .3704 .1 .3 .9),
             }
         }
     }
@@ -185,6 +189,10 @@ mod attestation {
         #[arg(value_name = "att-report-path", required = true)]
         pub att_report_path: PathBuf,
 
+        /// Specify the processor model to verify the attestation report.
+        #[arg(short, long, value_name = "processor-model", ignore_case = true)]
+        pub processor_model: Option<ProcType>,
+
         /// Run the TCB Verification Exclusively.
         #[arg(short, long, conflicts_with = "signature")]
         pub tcb: bool,
@@ -208,8 +216,9 @@ mod attestation {
         // Get the attestation report signature
         let ar_signature = EcdsaSig::try_from(&att_report.signature)
             .context("Failed to get ECDSA Signature from attestation report.")?;
-        let signed_bytes = &bincode::serialize(&att_report)
-            .context("Failed to get the signed bytes from the attestation report.")?[0x0..0x2A0];
+        let mut report_bytes = Vec::new();
+        att_report.write_bytes(&mut report_bytes)?;
+        let signed_bytes = &report_bytes[0x0..0x2A0];
 
         let mut hasher: Sha384 = Sha384::new();
 
@@ -293,6 +302,7 @@ mod attestation {
     fn verify_attestation_tcb(
         vcek: Certificate,
         att_report: AttestationReport,
+        proc_model: ProcType,
         quiet: bool,
     ) -> Result<()> {
         let vek_der = vcek.to_der().context("Could not convert VEK to der.")?;
@@ -359,7 +369,7 @@ mod attestation {
         // Compare HWID information only on VCEK
         if common_name == CertType::VCEK {
             if let Some(cert_hwid) = extensions.get(&SnpOid::HwId.oid()) {
-                if !check_cert_bytes(cert_hwid, &att_report.chip_id) {
+                if !check_cert_bytes(cert_hwid, &*att_report.chip_id) {
                     return Err(anyhow::anyhow!(
                         "Report TCB ID and Certificate ID mismatch encountered."
                     ));
@@ -370,6 +380,32 @@ mod attestation {
             }
         }
 
+        if proc_model == ProcType::Turin {
+            if att_report.version < 3 {
+                return Err(anyhow::anyhow!(
+                    "Turin Attestation is not supported in version 2 of the report."
+                ));
+            }
+            if let Some(cert_fmc) = extensions.get(&SnpOid::Fmc.oid()) {
+                let fmc = if let Some(fmc) = att_report.reported_tcb.fmc {
+                    fmc
+                } else {
+                    return Err(anyhow::anyhow!(
+                        "Attestation report TCB FMC is not present in the report. it is expecter for a {} model.", proc_model
+                    ));
+                };
+
+                if !check_cert_bytes(cert_fmc, fmc.to_le_bytes().as_slice()) {
+                    return Err(anyhow::anyhow!(
+                        "Report TCB FMC and Certificate FMC mismatch encountered."
+                    ));
+                }
+                if !quiet {
+                    println!("Reported TCB FMC from certificate matches the attestation report.");
+                }
+            }
+        }
+
         Ok(())
     }
 
@@ -378,10 +414,18 @@ mod attestation {
         let att_report = if !args.att_report_path.exists() {
             return Err(anyhow::anyhow!("No attestation report was found. Provide an attestation report to request VEK from the KDS."));
         } else {
-            report::read_report(args.att_report_path)
+            report::read_report(args.att_report_path.clone())
                 .context("Could not open attestation report")?
         };
 
+        let proc_model = if let Some(proc_model) = args.processor_model {
+            proc_model
+        } else {
+            let att_report = report::read_report(args.att_report_path.clone())
+                .context("Could not open attestation report")?;
+            get_processor_model(att_report)?
+        };
+
         // Get VEK and its public key.
         let (vek_path, vek_type) = match find_cert_in_dir(&args.certs_dir, "vlek") {
             Ok(vlek_path) => (vlek_path, "vlek"),
@@ -393,13 +437,13 @@ mod attestation {
 
         if args.tcb || args.signature {
             if args.tcb {
-                verify_attestation_tcb(vek.clone(), att_report, quiet)?;
+                verify_attestation_tcb(vek.clone(), att_report, proc_model, quiet)?;
             }
             if args.signature {
                 verify_attestation_signature(vek, att_report, quiet)?;
             }
         } else {
-            verify_attestation_tcb(vek.clone(), att_report, quiet)?;
+            verify_attestation_tcb(vek.clone(), att_report, proc_model, quiet)?;
             verify_attestation_signature(vek, att_report, quiet)?;
         }
 


Reviews:
user: login: larrydewey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T14:34:51Z
user: login: DGonzalezVillal
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-02T16:11:57Z
user: login: larrydewey
body: Need to remove the `unwrap()` unless you can document that it will never fail.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T17:18:44Z
user: login: tylerfanelli
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-04-02T18:53:55Z
user: login: larrydewey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T19:33:40Z
user: login: DGonzalezVillal
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T20:05:32Z
user: login: DGonzalezVillal
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T20:07:27Z
user: login: DGonzalezVillal
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T20:48:40Z
user: login: DGonzalezVillal
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T20:50:09Z
user: login: tylerfanelli
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T20:51:21Z
user: login: tylerfanelli
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T20:55:33Z
user: login: tylerfanelli
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T20:58:38Z
user: login: DGonzalezVillal
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T21:10:07Z
user: login: DGonzalezVillal
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T21:15:59Z
user: login: DGonzalezVillal
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T21:17:53Z
user: login: larrydewey
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-17T20:07:15Z
user: login: larrydewey
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T17:02:46Z
user: login: tylerfanelli
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-24T00:10:14Z
user: login: larrydewey
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-24T15:13:40Z

Review comments:
diff_hunk: @@ -240,6 +290,7 @@ mod vcek {
             report::read_report(att_report_path).context("Could not open attestation report")?
         };
 
+        // Get hardware id
path: src/fetch.rs
user: login: larrydewey
body: While not within the scope of this PR, we should probably introduce some logic here for when MASK_CHIP_ID is set to true.
created_at: 2025-04-02T14:34:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -248,15 +299,38 @@ mod vcek {
             _ => hex::encode(att_report.chip_id),
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
+                if att_report.version < 3 {
+                    return Err(anyhow::anyhow!(
+                        "Turin attestation is not supported in version 2 reports"
+                    ));
+                } else {
+                    format!(
+                        "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
+                    {hw_id}?fmcSPL={:02}&blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
+                        processor_model.to_kds_url(),
+                        att_report.reported_tcb.fmc.unwrap(),
path: src/fetch.rs
user: login: larrydewey
body: We shouldn't be using `unwrap()` here, unless we can guarantee it will never fail.
created_at: 2025-04-02T14:57:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -240,6 +290,7 @@ mod vcek {
             report::read_report(att_report_path).context("Could not open attestation report")?
         };
 
+        // Get hardware id
path: src/fetch.rs
user: login: DGonzalezVillal
body: A Quick question around MASK_CHIP_ID. When it is enabled, we are assuming the user is using VLEK as their attestation endorsement key right? You can't verify VCEK if MASK_CHIP_ID is enabled? Because I think you can't fetch the VCEK from the KDS if the hw_id is 0's. So What I'm thinking here is just adding an error message letting people know Mask Chip is enabled and you can't fetch VCEK with that enabled. Does that sound correct?
created_at: 2025-04-02T16:11:57Z
author_association: MEMBER
diff_hunk: @@ -60,32 +60,38 @@ COMMANDS
     -h, --help  show a help message
 
 *snpguest fetch ca*::
-    usage: snpguest fetch ca $ENCODING $PROCESSOR_MODEL $CERTS_DIR
+    usage: snpguest fetch ca $ENCODING $CERTS_DIR $ATT_REPORT_PATH [-p, --processor-model] $PROCESSOR_MODEL [-E --endorser] $ENDORSEMENT
path: docs/snpguest.1.adoc
user: login: tylerfanelli
body: Is the optional processor model argument for users of attestation reports < v3? If so, shouldn't the attestation report path be optional?
created_at: 2025-04-02T18:45:11Z
author_association: MEMBER
diff_hunk: @@ -105,6 +108,29 @@ impl fmt::Display for ProcType {
     }
 }
 
+pub fn get_processor_model(att_report: AttestationReport) -> Result<ProcType> {
+    if att_report.version < 3 {
+        return Err(anyhow::anyhow!(
+            "Attestation report version is too low to get cpu model"
+        ));
+    }
+    let cpu_fam = att_report.cpuid_fam_id.unwrap();
+    let cpu_mod = att_report.cpuid_mod_id.unwrap();
+
+    match cpu_fam {
+        0x19 => match cpu_mod {
+            0x0..=0xF => Ok(ProcType::Milan),
+            0x10..=0x1F | 0xA0..0xAF => Ok(ProcType::Genoa),
path: src/fetch.rs
user: login: tylerfanelli
body: Milan and Genoa use attestation report v3?
created_at: 2025-04-02T18:46:46Z
author_association: MEMBER
diff_hunk: @@ -170,8 +211,17 @@ mod cert_authority {
 
     // Fetch the ca from the kds and write it into the certs directory
     pub fn fetch_ca(args: Args) -> Result<()> {
+        let proc_model = if let Some(processor_model) = args.processor_model {
+            processor_model
+        } else if let Some(att_report) = args.att_report {
+            let att_report =
path: src/fetch.rs
user: login: tylerfanelli
body: ```suggestion
            let report =
```
created_at: 2025-04-02T18:48:27Z
author_association: MEMBER
diff_hunk: @@ -170,8 +211,17 @@ mod cert_authority {
 
     // Fetch the ca from the kds and write it into the certs directory
     pub fn fetch_ca(args: Args) -> Result<()> {
+        let proc_model = if let Some(processor_model) = args.processor_model {
+            processor_model
+        } else if let Some(att_report) = args.att_report {
+            let att_report =
+                report::read_report(att_report).context("Could not open attestation report")?;
+            get_processor_model(att_report)?
+        } else {
+            return Err(anyhow::anyhow!("No processor model provided"));
path: src/fetch.rs
user: login: tylerfanelli
body: ```suggestion
            return Err(anyhow::anyhow!("No processor model provided, attestation report version < 3"));
```
created_at: 2025-04-02T18:48:49Z
author_association: MEMBER
diff_hunk: @@ -248,15 +299,38 @@ mod vcek {
             _ => hex::encode(att_report.chip_id),
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
path: src/fetch.rs
user: login: tylerfanelli
body: So Turin can use attestation report version < 3 too? This is strange.
created_at: 2025-04-02T18:49:25Z
author_association: MEMBER
diff_hunk: @@ -248,15 +299,38 @@ mod vcek {
             _ => hex::encode(att_report.chip_id),
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
+                if att_report.version < 3 {
+                    return Err(anyhow::anyhow!(
+                        "Turin attestation is not supported in version 2 reports"
+                    ));
+                } else {
+                    format!(
+                        "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
+                    {hw_id}?fmcSPL={:02}&blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
+                        processor_model.to_kds_url(),
+                        att_report.reported_tcb.fmc.unwrap(),
path: src/fetch.rs
user: login: tylerfanelli
body: Right, it's sometimes `None`, correct?
created_at: 2025-04-02T18:50:03Z
author_association: MEMBER
diff_hunk: @@ -15,10 +15,12 @@ use sev::firmware::guest::{AttestationReport, Firmware};
 
 // Read a bin-formatted attestation report.
 pub fn read_report(att_report_path: PathBuf) -> Result<AttestationReport, anyhow::Error> {
-    let attestation_file = fs::File::open(att_report_path)?;
+    let mut attestation_file = fs::File::open(att_report_path)?;
 
-    let attestation_report = bincode::deserialize_from(attestation_file)
-        .context("Could not parse attestation report.")?;
+    let mut report_bytes = Vec::new();
+    attestation_file.read_to_end(&mut report_bytes).unwrap();
path: src/report.rs
user: login: tylerfanelli
body: Should likely fail gracefully here for improper formatting of the attestation report bytes in the file.
created_at: 2025-04-02T18:52:49Z
author_association: MEMBER
diff_hunk: @@ -105,6 +108,29 @@ impl fmt::Display for ProcType {
     }
 }
 
+pub fn get_processor_model(att_report: AttestationReport) -> Result<ProcType> {
+    if att_report.version < 3 {
+        return Err(anyhow::anyhow!(
+            "Attestation report version is too low to get cpu model"
+        ));
+    }
+    let cpu_fam = att_report.cpuid_fam_id.unwrap();
+    let cpu_mod = att_report.cpuid_mod_id.unwrap();
+
+    match cpu_fam {
+        0x19 => match cpu_mod {
+            0x0..=0xF => Ok(ProcType::Milan),
+            0x10..=0x1F | 0xA0..0xAF => Ok(ProcType::Genoa),
path: src/fetch.rs
user: login: larrydewey
body: They can, yes.
created_at: 2025-04-02T19:33:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -60,32 +60,38 @@ COMMANDS
     -h, --help  show a help message
 
 *snpguest fetch ca*::
-    usage: snpguest fetch ca $ENCODING $PROCESSOR_MODEL $CERTS_DIR
+    usage: snpguest fetch ca $ENCODING $CERTS_DIR $ATT_REPORT_PATH [-p, --processor-model] $PROCESSOR_MODEL [-E --endorser] $ENDORSEMENT
path: docs/snpguest.1.adoc
user: login: DGonzalezVillal
body: What I was thinking is that we keep functionality equal between the VCEK and CA fetch. Since the attestation report is already required for the VCEK, I thought make it mandatory for the CA. And then I kept the -p optional flag in the rare case the user is interested in fetching the certs for a proc that is not in their host. I think we also default behavior to what is latest too. So, assume people have the latest, but offer functionality if that's not the case.

I would also appreciate your thoughts on this too @larrydewey.
created_at: 2025-04-03T20:05:31Z
author_association: MEMBER
diff_hunk: @@ -105,6 +108,29 @@ impl fmt::Display for ProcType {
     }
 }
 
+pub fn get_processor_model(att_report: AttestationReport) -> Result<ProcType> {
+    if att_report.version < 3 {
+        return Err(anyhow::anyhow!(
+            "Attestation report version is too low to get cpu model"
+        ));
+    }
+    let cpu_fam = att_report.cpuid_fam_id.unwrap();
+    let cpu_mod = att_report.cpuid_mod_id.unwrap();
+
+    match cpu_fam {
+        0x19 => match cpu_mod {
+            0x0..=0xF => Ok(ProcType::Milan),
+            0x10..=0x1F | 0xA0..0xAF => Ok(ProcType::Genoa),
path: src/fetch.rs
user: login: DGonzalezVillal
body: The report is available in all the latest firmwares. 
created_at: 2025-04-03T20:07:26Z
author_association: MEMBER
diff_hunk: @@ -248,15 +299,38 @@ mod vcek {
             _ => hex::encode(att_report.chip_id),
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
path: src/fetch.rs
user: login: DGonzalezVillal
body: Yeah, we agree that handling it is complicated. I just think that if we have Turin users, we say they need to have version 3 or newer. Apparently there are Turin's out there with firmware that contains version 2 of the report, but in that case we just have no idea of what TCB to use. We could default to the milan/genoa tcb, but then attestation will be wrong. 

created_at: 2025-04-03T20:48:39Z
author_association: MEMBER
diff_hunk: @@ -248,15 +299,38 @@ mod vcek {
             _ => hex::encode(att_report.chip_id),
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
+                if att_report.version < 3 {
+                    return Err(anyhow::anyhow!(
+                        "Turin attestation is not supported in version 2 reports"
+                    ));
+                } else {
+                    format!(
+                        "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
+                    {hw_id}?fmcSPL={:02}&blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
+                        processor_model.to_kds_url(),
+                        att_report.reported_tcb.fmc.unwrap(),
path: src/fetch.rs
user: login: DGonzalezVillal
body: If the proc type is turin and the report is version 3 or newer, fmc should always be present, or that's what I understand.
created_at: 2025-04-03T20:50:08Z
author_association: MEMBER
diff_hunk: @@ -248,15 +299,38 @@ mod vcek {
             _ => hex::encode(att_report.chip_id),
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
path: src/fetch.rs
user: login: tylerfanelli
body: > Yeah, we agree that handling it is complicated. I just think that if we have Turin users, we say they need to have version 3 or newer.

We should probably enforce that here if it's a de facto requirement.

created_at: 2025-04-03T20:51:21Z
author_association: MEMBER
diff_hunk: @@ -248,15 +299,38 @@ mod vcek {
             _ => hex::encode(att_report.chip_id),
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
+                if att_report.version < 3 {
+                    return Err(anyhow::anyhow!(
+                        "Turin attestation is not supported in version 2 reports"
+                    ));
+                } else {
+                    format!(
+                        "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
+                    {hw_id}?fmcSPL={:02}&blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
+                        processor_model.to_kds_url(),
+                        att_report.reported_tcb.fmc.unwrap(),
path: src/fetch.rs
user: login: tylerfanelli
body: Then a graceful error with a message like `Turin processor with attestation report v3 detected, FMC required` (or something of the sort) would probably be a good way to handle.
created_at: 2025-04-03T20:55:32Z
author_association: MEMBER
diff_hunk: @@ -60,32 +60,38 @@ COMMANDS
     -h, --help  show a help message
 
 *snpguest fetch ca*::
-    usage: snpguest fetch ca $ENCODING $PROCESSOR_MODEL $CERTS_DIR
+    usage: snpguest fetch ca $ENCODING $CERTS_DIR $ATT_REPORT_PATH [-p, --processor-model] $PROCESSOR_MODEL [-E --endorser] $ENDORSEMENT
path: docs/snpguest.1.adoc
user: login: tylerfanelli
body: > What I was thinking is that we keep functionality equal between the VCEK and CA fetch. Since the attestation report is already required for the VCEK, I thought make it mandatory for the CA.

It's required for the VCEK because the KDS URL to fetch the VCEK is derived from some fields in the attestation report. This is not the case with the CA chain.

> And then I kept the -p optional flag in the rare case the user is interested in fetching the certs for a proc that is not in their host. I think we also default behavior to what is latest too. So, assume people have the latest, but offer functionality if that's not the case.
>

For report versions >= v3, the report can be used to derive the processor model and fetch the correct CA chain, but for < v3 the report is unused. Therefore I think it should be optional (with some special handling with Turin+ likely needed).
created_at: 2025-04-03T20:58:38Z
author_association: MEMBER
diff_hunk: @@ -248,15 +299,38 @@ mod vcek {
             _ => hex::encode(att_report.chip_id),
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
path: src/fetch.rs
user: login: DGonzalezVillal
body: I have an if check when building the vcek url (line 313), is that what you mean? or do you meant doing a check before that?
created_at: 2025-04-03T21:10:06Z
author_association: MEMBER
diff_hunk: @@ -60,32 +60,38 @@ COMMANDS
     -h, --help  show a help message
 
 *snpguest fetch ca*::
-    usage: snpguest fetch ca $ENCODING $PROCESSOR_MODEL $CERTS_DIR
+    usage: snpguest fetch ca $ENCODING $CERTS_DIR $ATT_REPORT_PATH [-p, --processor-model] $PROCESSOR_MODEL [-E --endorser] $ENDORSEMENT
path: docs/snpguest.1.adoc
user: login: DGonzalezVillal
body: Ok in that case I'll return it to the previous behavior, and make the report the optional paramater. 
created_at: 2025-04-03T21:15:58Z
author_association: MEMBER
diff_hunk: @@ -248,15 +299,38 @@ mod vcek {
             _ => hex::encode(att_report.chip_id),
         };
 
-        let vcek_url: String = format!(
-            "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
-            {hw_id}?blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
-            processor_model.to_kds_url(),
-            att_report.reported_tcb.bootloader,
-            att_report.reported_tcb.tee,
-            att_report.reported_tcb.snp,
-            att_report.reported_tcb.microcode
-        );
+        // Request VCEK from KDS
+        let vcek_url: String = match processor_model {
+            ProcType::Turin => {
+                if att_report.version < 3 {
+                    return Err(anyhow::anyhow!(
+                        "Turin attestation is not supported in version 2 reports"
+                    ));
+                } else {
+                    format!(
+                        "{KDS_CERT_SITE}{KDS_VCEK}/{}/\
+                    {hw_id}?fmcSPL={:02}&blSPL={:02}&teeSPL={:02}&snpSPL={:02}&ucodeSPL={:02}",
+                        processor_model.to_kds_url(),
+                        att_report.reported_tcb.fmc.unwrap(),
path: src/fetch.rs
user: login: DGonzalezVillal
body: Ok i'll add a graceful error.
created_at: 2025-04-03T21:17:51Z
author_association: MEMBER
diff_hunk: @@ -105,6 +108,46 @@ impl fmt::Display for ProcType {
     }
 }
 
+pub fn get_processor_model(att_report: AttestationReport) -> Result<ProcType> {
+    if att_report.version < 3 {
+        if att_report.key_info.mask_chip_key() {
+            return Err(anyhow::anyhow!(
+                "Attestation report version is too and mask chip key is set to 1, there is no way of getting the cpu model."
+            ));
+        } else {
+            let chip_id = *att_report.chip_id;
+            if chip_id[8..64] == [0; 56] {
+                return Ok(ProcType::Turin);
+            } else {
+                return Err(anyhow::anyhow!(
+                    "Attestation report could be either Milan or Genoa."
+                ));
+            }
+        }
path: src/fetch.rs
user: login: larrydewey
body: As a reminder, we learned that `MaskChipKey` doesn't indicate if the MASK_CHIP_ID is set or not. Just which key is being used for signing. We will just need to check for all zeroes first.
created_at: 2025-04-23T17:02:40Z
author_association: CONTRIBUTOR

PR comments:
user: login: DGonzalezVillal
created_at: 2025-04-01T19:53:26Z
body: @larrydewey @tylerfanelli can i get review

author_association: MEMBER
user: login: tylerfanelli
created_at: 2025-04-02T05:47:35Z
body: nit: In the commit message s/chich/which.
author_association: MEMBER
user: login: DGonzalezVillal
created_at: 2025-04-03T21:32:35Z
body: Addressed most comments, waiting on the one conversation. Feel free to re-review. Thanks! @larrydewey @tylerfanelli 
author_association: MEMBER
user: login: DGonzalezVillal
created_at: 2025-04-17T20:06:14Z
body: @larrydewey @tylerfanelli 
author_association: MEMBER