├── app ├── verbose-report ├── Dockerfile ├── main.py └── verbose-report.c ├── media └── hello-world-cc.png ├── CHANGELOG.md ├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── LICENSE.md ├── README.md ├── template.json ├── CONTRIBUTING.md └── .gitignore /app/verbose-report: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-confidential-hello-world/main/app/verbose-report -------------------------------------------------------------------------------- /media/hello-world-cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/aci-confidential-hello-world/main/media/hello-world-cc.png -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [project-title] Changelog 2 | 3 | 4 | # x.y.z (yyyy-mm-dd) 5 | 6 | *Features* 7 | * ... 8 | 9 | *Bug Fixes* 10 | * ... 11 | 12 | *Breaking Changes* 13 | * ... 14 | -------------------------------------------------------------------------------- /app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.17.2 2 | RUN apk update && apk add python3 py3-pip --no-cache 3 | RUN pip3 install flask --no-cache-dir 4 | 5 | # all commands start from this directory 6 | WORKDIR /app 7 | 8 | # copy all files from this folder to working directory (ignores files in .dockerignore) 9 | COPY Dockerfile main.py verbose-report verbose-report.c /app/ 10 | 11 | EXPOSE 80 12 | ENV PYTHONUNBUFFERED=1 13 | 14 | # set the start command 15 | CMD [ "python3", "main.py" ] 16 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | > Please provide us with the following information: 5 | > --------------------------------------------------------------- 6 | 7 | ### This issue is for a: (mark with an `x`) 8 | ``` 9 | - [ ] bug report -> please search issues before submitting 10 | - [ ] feature request 11 | - [ ] documentation issue or request 12 | - [ ] regression (a behavior that used to work and stopped in a new release) 13 | ``` 14 | 15 | ### Minimal steps to reproduce 16 | > 17 | 18 | ### Any log messages given by the failure 19 | > 20 | 21 | ### Expected/desired behavior 22 | > 23 | 24 | ### OS and Version? 25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?) 26 | 27 | ### Versions 28 | > 29 | 30 | ### Mention any other details that might be useful 31 | 32 | > --------------------------------------------------------------- 33 | > Thanks! We'll be in touch soon. 34 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | 3 | * ... 4 | 5 | ## Does this introduce a breaking change? 6 | 7 | ``` 8 | [ ] Yes 9 | [ ] No 10 | ``` 11 | 12 | ## Pull Request Type 13 | What kind of change does this Pull Request introduce? 14 | 15 | 16 | ``` 17 | [ ] Bugfix 18 | [ ] Feature 19 | [ ] Code style update (formatting, local variables) 20 | [ ] Refactoring (no functional changes, no api changes) 21 | [ ] Documentation content changes 22 | [ ] Other... Please describe: 23 | ``` 24 | 25 | ## How to Test 26 | * Get the code 27 | 28 | ``` 29 | git clone [repo-address] 30 | cd [repo-name] 31 | git checkout [branch-name] 32 | npm install 33 | ``` 34 | 35 | * Test the code 36 | 37 | ``` 38 | ``` 39 | 40 | ## What to Check 41 | Verify that the following are valid 42 | * ... 43 | 44 | ## Other Information 45 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATED 2 | 3 | The contents of this repository have been moved to the [Microsoft Organization](https://github.com/microsoft/confidential-container-demos/tree/main/hello-world/ACI) 4 | 5 | --- 6 | page_type: sample 7 | languages: 8 | - python 9 | - C 10 | products: 11 | - azure-container-instances 12 | - azure attestation-service 13 | description: "Confidential containers on ACI samples" 14 | urlFragment: confidential-aci-samples 15 | --- 16 | 17 | 18 | # Azure Container Instances Confidential Hello World 19 | 20 | This sample is a basic Python application used to demonstrate [Confidential Containers on Azure Container Instances](aka.ms/aci). In this sample an AMD SEV SNP report containing the container groups firmware measurements will be displayed in a Python Flask web application. 21 | 22 | The packaged version of this application is available on [Microsoft Container Registry](https://registry.hub.docker.com/_/microsoft-azuredocs-aci-helloworld?tab=description). 23 | 24 | ![Hello World Hardware Report](./media/hello-world-cc.png) 25 | 26 | ## Getting Started 27 | 28 | ### Tutorials 29 | 30 | * [Deploy via Portal](https://aka.ms/aciccportal) 31 | * [Deploy via ARM with a custom confidential computing enforcement policy](https://aka.ms/aciccarm) 32 | 33 | 34 | ## Contributing 35 | 36 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 37 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 38 | the rights to use your contribution. For details, visit 39 | 40 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 41 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 42 | provided by the bot. You will only need to do this once across all repos using our CLA. 43 | 44 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 45 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 46 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 47 | -------------------------------------------------------------------------------- /app/main.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import string 3 | import os 4 | import stat 5 | # Importing flask module in the project is mandatory 6 | # An object of Flask class is our WSGI application. 7 | from flask import Flask 8 | # Flask constructor takes the name of 9 | # current module (__name__) as argument. 10 | app = Flask(__name__) 11 | 12 | # The route() function of the Flask class is a decorator, 13 | # which tells the application which URL should call 14 | # the associated function. 15 | 16 | 17 | @app.route('/') 18 | def index(): 19 | filename = "./verbose-report" 20 | # make sure the file is executable 21 | if not os.access(filename, os.X_OK): 22 | # make it executable if it's not 23 | st = os.stat(filename) 24 | os.chmod(filename, st.st_mode | 25 | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) 26 | out = (subprocess.run(filename, 27 | capture_output=True, encoding="UTF-8")).stdout 28 | 29 | formatted_text = out.replace("\n", " ").split(" ") 30 | formatted_text = [x for x in formatted_text if x != ""] 31 | 32 | def is_hex(x): return all(c in string.hexdigits for c in x) 33 | 34 | out = [] 35 | temp_out = ["
"] 36 | counter = 0 37 | start_flag = False 38 | for item in formatted_text: 39 | # there are some headers before the actual data we want to display 40 | if "AMD" in item: 41 | start_flag = True 42 | 43 | if start_flag: 44 | # add a line break before and after each header 45 | if item.endswith(":"): 46 | temp_out.append(item) 47 | temp_out.append("
") 48 | # bold the header 49 | out.append("") 50 | out.append(" ".join(temp_out)) 51 | out.append("") 52 | temp_out = ["
"] 53 | counter = 0 54 | 55 | # these are the header words before the colon at the end of the line 56 | elif not is_hex(item): 57 | temp_out.append(item) 58 | counter = 0 59 | # fall-through case of data 60 | else: 61 | if counter == 2: 62 | out.append("
") 63 | counter = 0 64 | out.append(item) 65 | counter += 1 66 | 67 | # ACI image source 68 | image = "\"Microsoft
" 69 | style = """ 70 | 76 | """ 77 | # put everything together 78 | return ( 79 | style + 80 | "
" + "

Welcome to Confidential containers on Azure Container Instances!

" + 81 | image + " ".join(out) + 82 | "
" 83 | ) 84 | 85 | 86 | # main driver function 87 | if __name__ == '__main__': 88 | 89 | # run() method of Flask class runs the application 90 | # on the local development server. 91 | app.run(host='0.0.0.0', port=80) 92 | -------------------------------------------------------------------------------- /template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "name": { 6 | "type": "string", 7 | "defaultValue": "helloworld", 8 | "metadata": { 9 | "description": "Name for the container group" 10 | } 11 | }, 12 | "location": { 13 | "type": "string", 14 | "defaultValue": "North Europe", 15 | "metadata": { 16 | "description": "Location for all resources." 17 | } 18 | }, 19 | "image": { 20 | "type": "string", 21 | "defaultValue": "mcr.microsoft.com/aci/aci-confidential-helloworld:v1", 22 | "metadata": { 23 | "description": "Container image to deploy. Should be of the form repoName/imagename:tag for images stored in public Docker Hub, or a fully qualified URI for other registries. Images from private registries require additional registry credentials." 24 | } 25 | }, 26 | "port": { 27 | "type": "int", 28 | "defaultValue": 80, 29 | "metadata": { 30 | "description": "Port to open on the container and the public IP address." 31 | } 32 | }, 33 | "cpuCores": { 34 | "type": "int", 35 | "defaultValue": 1, 36 | "metadata": { 37 | "description": "The number of CPU cores to allocate to the container." 38 | } 39 | }, 40 | "memoryInGb": { 41 | "type": "int", 42 | "defaultValue": 1, 43 | "metadata": { 44 | "description": "The amount of memory to allocate to the container in gigabytes." 45 | } 46 | }, 47 | "restartPolicy": { 48 | "type": "string", 49 | "defaultValue": "Never", 50 | "allowedValues": [ 51 | "Always", 52 | "Never", 53 | "OnFailure" 54 | ], 55 | "metadata": { 56 | "description": "The behavior of Azure runtime if container has stopped." 57 | } 58 | } 59 | }, 60 | "resources": [ 61 | { 62 | "type": "Microsoft.ContainerInstance/containerGroups", 63 | "apiVersion": "2022-10-01-preview", 64 | "name": "[parameters('name')]", 65 | "location": "[parameters('location')]", 66 | "properties": { 67 | "confidentialComputeProperties": { 68 | "ccePolicy": "" 69 | }, 70 | "containers": [ 71 | { 72 | "name": "[parameters('name')]", 73 | "properties": { 74 | "image": "[parameters('image')]", 75 | "ports": [ 76 | { 77 | "port": "[parameters('port')]", 78 | "protocol": "TCP" 79 | } 80 | ], 81 | "resources": { 82 | "requests": { 83 | "cpu": "[parameters('cpuCores')]", 84 | "memoryInGB": "[parameters('memoryInGb')]" 85 | } 86 | } 87 | } 88 | } 89 | ], 90 | "sku": "Confidential", 91 | "osType": "Linux", 92 | "restartPolicy": "[parameters('restartPolicy')]", 93 | "ipAddress": { 94 | "type": "Public", 95 | "ports": [ 96 | { 97 | "port": "[parameters('port')]", 98 | "protocol": "TCP" 99 | } 100 | ] 101 | } 102 | } 103 | } 104 | ], 105 | "outputs": { 106 | "containerIPv4Address": { 107 | "type": "string", 108 | "value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups', parameters('name'))).ipAddress.ip]" 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to [project-title] 2 | 3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 5 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 6 | 7 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 8 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 9 | provided by the bot. You will only need to do this once across all repos using our CLA. 10 | 11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 14 | 15 | - [Code of Conduct](#coc) 16 | - [Issues and Bugs](#issue) 17 | - [Feature Requests](#feature) 18 | - [Submission Guidelines](#submit) 19 | 20 | ## Code of Conduct 21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 22 | 23 | ## Found an Issue? 24 | If you find a bug in the source code or a mistake in the documentation, you can help us by 25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can 26 | [submit a Pull Request](#submit-pr) with a fix. 27 | 28 | ## Want a Feature? 29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub 30 | Repository. If you would like to *implement* a new feature, please submit an issue with 31 | a proposal for your work first, to be sure that we can use it. 32 | 33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr). 34 | 35 | ## Submission Guidelines 36 | 37 | ### Submitting an Issue 38 | Before you submit an issue, search the archive, maybe your question was already answered. 39 | 40 | If your issue appears to be a bug, and hasn't been reported, open a new issue. 41 | Help us to maximize the effort we can spend fixing issues and adding new 42 | features, by not reporting duplicate issues. Providing the following information will increase the 43 | chances of your issue being dealt with quickly: 44 | 45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps 46 | * **Version** - what version is affected (e.g. 0.1.2) 47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you 48 | * **Browsers and Operating System** - is this a problem with all browsers? 49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps 50 | * **Related Issues** - has a similar issue been reported before? 51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be 52 | causing the problem (line of code or commit) 53 | 54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new]. 55 | 56 | ### Submitting a Pull Request (PR) 57 | Before you submit your Pull Request (PR) consider the following guidelines: 58 | 59 | * Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR 60 | that relates to your submission. You don't want to duplicate effort. 61 | 62 | * Make your changes in a new git fork: 63 | 64 | * Commit your changes using a descriptive commit message 65 | * Push your fork to GitHub: 66 | * In GitHub, create a pull request 67 | * If we suggest changes then: 68 | * Make the required updates. 69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request): 70 | 71 | ```shell 72 | git rebase master -i 73 | git push -f 74 | ``` 75 | 76 | That's it! Thank you for your contribution! 77 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /app/verbose-report.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* From sev-snp driver include/uapi/linux/psp-sev-guest.h */ 13 | 14 | struct sev_snp_guest_request { 15 | uint8_t req_msg_type; 16 | uint8_t rsp_msg_type; 17 | uint8_t msg_version; 18 | uint16_t request_len; 19 | uint64_t request_uaddr; 20 | uint16_t response_len; 21 | uint64_t response_uaddr; 22 | uint32_t error; /* firmware error code on failure (see psp-sev.h) */ 23 | }; 24 | 25 | enum snp_msg_type { 26 | SNP_MSG_TYPE_INVALID = 0, 27 | SNP_MSG_CPUID_REQ, 28 | SNP_MSG_CPUID_RSP, 29 | SNP_MSG_KEY_REQ, 30 | SNP_MSG_KEY_RSP, 31 | SNP_MSG_REPORT_REQ, 32 | SNP_MSG_REPORT_RSP, 33 | SNP_MSG_EXPORT_REQ, 34 | SNP_MSG_EXPORT_RSP, 35 | SNP_MSG_IMPORT_REQ, 36 | SNP_MSG_IMPORT_RSP, 37 | SNP_MSG_ABSORB_REQ, 38 | SNP_MSG_ABSORB_RSP, 39 | SNP_MSG_VMRK_REQ, 40 | SNP_MSG_VMRK_RSP, 41 | SNP_MSG_TYPE_MAX 42 | }; 43 | 44 | #define SEV_GUEST_IOC_TYPE 'S' 45 | #define SEV_SNP_GUEST_MSG_REQUEST _IOWR(SEV_GUEST_IOC_TYPE, 0x0, struct sev_snp_guest_request) 46 | #define SEV_SNP_GUEST_MSG_REPORT _IOWR(SEV_GUEST_IOC_TYPE, 0x1, struct sev_snp_guest_request) 47 | #define SEV_SNP_GUEST_MSG_KEY _IOWR(SEV_GUEST_IOC_TYPE, 0x2, struct sev_snp_guest_request) 48 | 49 | #define PRINT_VAL(ptr, field) printBytes(#field, (const uint8_t *)&(ptr->field), sizeof(ptr->field), true, false) 50 | #define PRINT_BYTES(ptr, field) printBytes(#field, (const uint8_t *)&(ptr->field), sizeof(ptr->field), false, false) 51 | #define BOLD_VAL(ptr, field) printBytes(#field, (const uint8_t *)&(ptr->field), sizeof(ptr->field), true, true) 52 | #define BOLD_BYTES(ptr, field) printBytes(#field, (const uint8_t *)&(ptr->field), sizeof(ptr->field), false, true) 53 | 54 | /* from SEV-SNP Firmware ABI Specification Table 20 */ 55 | 56 | typedef struct { 57 | uint8_t report_data[64]; 58 | uint32_t vmpl; 59 | uint8_t reserved[28]; // needs to be zero 60 | } msg_report_req; 61 | 62 | /* from SEV-SNP Firmware ABI Specification from Table 21 */ 63 | 64 | typedef struct { 65 | uint32_t version; // version no. of this attestation report. Set to 1 for this specification. Now 2 with production silicon 66 | uint32_t guest_svn; // The guest SVN 67 | uint64_t policy; // see table 8 - various settings 68 | __uint128_t family_id; // as provided at launch 69 | __uint128_t image_id; // as provided at launch 70 | uint32_t vmpl; // the request VMPL for the attestation report 71 | uint32_t signature_algo; 72 | uint64_t platform_version; // The install version of the firmware 73 | uint64_t platform_info; // information about the platform see table 22 74 | // not going to try to use bit fields for this next one. Too confusing as to which bit of the byte will be used. Make a mask if you need it 75 | uint32_t author_key_en; // 31 bits of reserved, must be zero, bottom bit indicates that the digest of the 76 | // author key is present in AUTHOR_KEY_DIGEST. Set to the value of GCTX.AuthorKeyEn. 77 | uint32_t reserved1; // must be zero 78 | uint8_t report_data[64]; // Guest provided data. 79 | uint8_t measurement[48]; // measurement calculated at launch 80 | uint8_t host_data[32]; // data provided by the hypervisor at launch 81 | uint8_t id_key_digest[48]; // SHA-384 digest of the ID public key that signed the ID block provided in SNP_LAUNCH_FINISH 82 | uint8_t author_key_digest[48]; // SHA-384 digest of the Author public key that certified the ID key, if provided in SNP_LAUNCH_FINISH. Zeros if author_key_en is 1 (sounds backwards to me). 83 | uint8_t report_id[32]; // Report ID of this guest. 84 | uint8_t report_id_ma[32]; // Report ID of this guest's mmigration agent. 85 | uint64_t reported_tcb; // Reported TCB version used to derive the VCEK that signed this report 86 | uint8_t reserved2[24]; // reserved 87 | uint8_t chip_id[64]; // Identifier unique to the chip 88 | uint8_t committed_svn[8]; // The current commited SVN of the firware (version 2 report feature) 89 | uint8_t committed_version[8]; // The current commited version of the firware 90 | uint8_t launch_svn[8]; // The SVN that this guest was launched or migrated at 91 | uint8_t reserved3[168]; // reserved 92 | uint8_t signature[512]; // Signature of this attestation report. See table 23. 93 | } snp_attestation_report; 94 | 95 | /* from SEV-SNP Firmware ABI Specification Table 22 */ 96 | 97 | typedef struct { 98 | uint32_t status; 99 | uint32_t report_size; 100 | uint8_t reserved[24]; 101 | snp_attestation_report report; 102 | uint8_t padding[64]; // padding to the size of SEV_SNP_REPORT_RSP_BUF_SZ (i.e., 1280 bytes) 103 | } msg_response_resp; 104 | 105 | bool formatAsHtml = false; 106 | 107 | void printBytes(const char *desc, const uint8_t *data, size_t len, bool swap, bool bold) 108 | { 109 | if (formatAsHtml) 110 | if (bold) 111 | printf("

%s: ", desc); 112 | else 113 | printf("

%s: ", desc); 114 | else 115 | printf(" %s: ", desc); 116 | int padding = 20 - strlen(desc); 117 | if (padding < 0) 118 | padding = 0; 119 | for (int count = 0; count < padding; count++) 120 | putchar(' '); 121 | 122 | for (size_t pos = 0; pos < len; pos++) { 123 | printf("%02x", data[swap ? len - pos - 1 : pos]); 124 | if (pos % 32 == 31) { 125 | if (formatAsHtml) 126 | printf("
"); 127 | printf("\n "); 128 | } else if (pos % 16 == 15) 129 | putchar(' '); 130 | } 131 | if (formatAsHtml) 132 | printf("

\n"); 133 | else 134 | printf("\n"); 135 | } 136 | 137 | void printReport(const snp_attestation_report *r) 138 | { 139 | if (formatAsHtml) 140 | printf("

AMD SEV-SNP Attestation Report:

\n"); 141 | else 142 | printf("AMD SEV-SNP Attestation Report:\n"); 143 | PRINT_VAL(r, version); // print the version as an actual number 144 | PRINT_VAL(r, guest_svn); 145 | PRINT_VAL(r, policy); 146 | PRINT_VAL(r, family_id); 147 | PRINT_VAL(r, image_id); 148 | PRINT_VAL(r, vmpl); 149 | PRINT_VAL(r, signature_algo); 150 | PRINT_BYTES(r, platform_version); // dump the platform version as hex bytes 151 | PRINT_BYTES(r, platform_info); 152 | PRINT_VAL(r, author_key_en); 153 | PRINT_VAL(r, reserved1); 154 | BOLD_BYTES(r, report_data); 155 | BOLD_BYTES(r, measurement); 156 | BOLD_BYTES(r, host_data); 157 | PRINT_BYTES(r, id_key_digest); 158 | PRINT_BYTES(r, author_key_digest); 159 | PRINT_BYTES(r, report_id); 160 | PRINT_BYTES(r, report_id_ma); 161 | PRINT_VAL(r, reported_tcb); 162 | PRINT_BYTES(r, reserved2); 163 | BOLD_BYTES(r, chip_id); 164 | PRINT_BYTES(r, committed_svn); 165 | PRINT_BYTES(r, committed_version); 166 | PRINT_BYTES(r, launch_svn); 167 | PRINT_BYTES(r, reserved3); 168 | BOLD_BYTES(r, signature); 169 | } 170 | 171 | uint8_t* decodeHexString(char *hexstring) 172 | { 173 | size_t len = strlen(hexstring); 174 | uint8_t *byte_array = (uint8_t*) malloc(strlen(hexstring)*sizeof(uint8_t)); 175 | 176 | for (size_t i = 0; i < len; i+=2) { 177 | sscanf(hexstring, "%2hhx", &byte_array[i/2]); 178 | hexstring += 2; 179 | } 180 | 181 | return byte_array; 182 | } 183 | 184 | 185 | int main(int argc, char** argv) 186 | { 187 | msg_report_req msg_report_in; 188 | msg_response_resp msg_report_out; 189 | 190 | int fd; 191 | int i; 192 | int rc; 193 | bool hexBlob = false; 194 | 195 | struct sev_snp_guest_request payload = { 196 | .req_msg_type = SNP_MSG_REPORT_REQ, 197 | .rsp_msg_type = SNP_MSG_REPORT_RSP, 198 | .msg_version = 1, 199 | .request_len = sizeof(msg_report_in), 200 | .request_uaddr = (uint64_t) (void*) &msg_report_in, 201 | .response_len = sizeof(msg_report_out), 202 | .response_uaddr = (uint64_t) (void*) &msg_report_out, 203 | .error = 0 204 | }; 205 | 206 | if (argc > 1 && !strcmp(argv[1], "--help")) { 207 | printf("%s: [--help|--html|--raw|--example]\n", argv[0]); 208 | exit(0); 209 | } 210 | 211 | if (argc > 1 && !strcmp(argv[1], "--html")) { 212 | formatAsHtml = true; 213 | argc--; 214 | argv++; 215 | } 216 | 217 | if (argc > 1 && !strcmp(argv[1], "--raw")) { 218 | hexBlob = true; 219 | argc--; 220 | argv++; 221 | } 222 | 223 | // use --example to get a canned report, used to help debug exposing reports via HTTP etc 224 | if (argc == 2 && !strcmp(argv[1], "--example")) { 225 | uint8_t *default_report = decodeHexString("01000000010000001f00030000000000010000000000000000000000000000000200000000000000000000000000000000000000010000000000000000000028010000000000000000000000000000007ab000a323b3c873f5b81bbe584e7c1a26bcf40dc27e00f8e0d144b1ed2d14f10000000000000000000000000000000000000000000000000000000000000000e29af700e85b39996fa38226d2804b78cad746ffef4477360a61b47874bdecd640f9d32f5ff64a55baad3c545484d9ed28603a3ea835a83bd688b0ec1dcb36b6b8c22412e5b63115b75db8628b989bc598c475ca5f7683e8d351e7e789a1baff19041750567161ad52bf0d152bd76d7c6f313d0a0fd72d0089692c18f521155800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040aea62690b08eb6d680392c9a9b3db56a9b3cc44083b9da31fb88bcfc493407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000028000000000000000000000000000000000000000000000000e6c86796cd44b0bc6b7c0d4fdab33e2807e14b5fc4538b3750921169d97bcf4447c7d3ab2a7c25f74c1641e2885c1011d025cc536f5c9a2504713136c7877f480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003131c0f3e7be5c6e400f22404596e1874381e99d03de45ef8b97eee0a0fa93a4911550330343f14dddbbd6c0db83744f000000000000000000000000000000000000000000000000db07c83c5e6162c2387f3b76cd547672657f6a5df99df98efee7c15349320d83e086c5003ec43050a9b18d1c39dedc340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); 226 | if (hexBlob) { 227 | printBytes("Raw example report", (const uint8_t *)default_report, sizeof(snp_attestation_report), false, false); 228 | } else { 229 | printReport((snp_attestation_report *)default_report); 230 | } 231 | exit(0); 232 | } 233 | 234 | memset((void*) &msg_report_in, 0, sizeof(msg_report_in)); 235 | memset((void*) &msg_report_out, 0, sizeof(msg_report_out)); 236 | // default to zeros 237 | memset(msg_report_in.report_data, 0x00, sizeof(msg_report_in.report_data)); 238 | // sha-512 key configuration structure to be used as report_data 239 | if (argc >1) { 240 | char *hexstring = argv[1]; 241 | size_t to_copy = (strlen(hexstring)+1)/2; 242 | if (to_copy > sizeof(msg_report_in.report_data)) 243 | to_copy = sizeof(msg_report_in.report_data); 244 | 245 | for (size_t i = 0; i < to_copy; i++) { 246 | sscanf(hexstring, "%2hhx", &msg_report_in.report_data[i]); 247 | hexstring += 2; 248 | } 249 | } 250 | 251 | fd = open("/dev/sev", O_RDWR | O_CLOEXEC); 252 | 253 | if (fd < 0) { 254 | printf("Failed to open /dev/sev\n"); 255 | exit(-1); 256 | } 257 | 258 | rc = ioctl(fd, SEV_SNP_GUEST_MSG_REPORT, &payload); 259 | 260 | if (rc < 0) { 261 | printf("Failed to issue ioctl SEV_SNP_GUEST_MSG_REPORT\n"); 262 | exit(-1); 263 | } 264 | 265 | if (!formatAsHtml && !hexBlob) { 266 | printf("Response header:\n"); 267 | 268 | uint8_t *hdr = (uint8_t*) &msg_report_out; 269 | 270 | for (i = 0; i < 32; i++) { 271 | printf("%02x", hdr[i]); 272 | if (i % 16 == 15) 273 | printf("\n"); 274 | else 275 | printf(" "); 276 | } 277 | } 278 | 279 | if (hexBlob) { 280 | printBytes("Raw report", (const uint8_t *)&msg_report_out.report, sizeof(msg_report_out.report), false, false); 281 | } else { 282 | printReport(&msg_report_out.report); 283 | } 284 | exit(0); 285 | } 286 | --------------------------------------------------------------------------------