├── .github ├── CODEOWNERS ├── PULL_REQUEST_TEMPLATE.md ├── not-grep.toml └── workflows │ ├── ci_static-analysis.yaml │ └── repo-sync.yml ├── .gitignore ├── .markdownlint.json ├── .prettierignore ├── .prettierrc.toml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── LICENSE-SAMPLECODE ├── LICENSE-SUMMARY ├── README.md ├── VERSIONING.md ├── changes ├── 2020-05-13_remove-keyring-trace │ ├── background.md │ └── change.md ├── 2020-06-04_how-to-fail-with-keyrings │ ├── background.md │ └── change.md ├── 2020-06-09_wrapping-key-identifiers │ └── change.md ├── 2020-06-16_required-examples │ └── change.md ├── 2020-06-17_encrypt-max-plaintext-length-input │ └── change.md ├── 2020-07-01_aws-kms-keyring-redesign │ ├── background.md │ └── change.md ├── 2020-07-06_clarify-streaming-encrypt-decrypt │ └── change.md ├── 2020-07-13_detect-base64-encoded-messages │ └── change.md ├── 2020-07-14_multi-keyring-require-generation │ └── change.md ├── 2020-07-14_refactor-cmc-spec │ └── change.md ├── 2020-07-15_clarify-caching-cmm-init-params │ └── change.md ├── 2020-07-15_encryption-context-reserved-prefix │ └── change.md ├── 2020-07-15_specify-behavior-for-raw-aes-keyring-for-invalid-EC │ └── change.md ├── 2020-07-17_cache-entry-identifier-formulas │ └── change.md ├── 2020-07-20_put-cache-entry-returns-nothing │ └── change.md ├── 2022-06-19_seperate_material_providers │ ├── background.md │ └── change.md ├── 2022-11-14_encryption_context_on_decrypt │ ├── background.md │ ├── encryption_context_use_cases.md │ └── proposal.md ├── 2023-06-19_thread_safe_cache │ ├── background.md │ └── change.md ├── 2023_7_12_update-keystore-structure │ ├── background.md │ └── proposal.md ├── 2024-03-12_ecdh-keyring │ ├── background.md │ └── change.md ├── 2024-05-20-keystore-kms-config │ └── change.md ├── 2024-09-13_cache-across-hierarchical-keyrings │ ├── background.md │ └── change.md ├── 2024-6-17_key-store-persistance │ ├── background.md │ └── proposed.smithy └── 2025-01-16_key-store-mitigate-update-race │ └── background.md ├── ci └── prettify.sh ├── client-apis ├── client.md ├── decrypt.md ├── encrypt.md └── streaming.md ├── data-format ├── message-body-aad.md ├── message-body.md ├── message-footer.md ├── message-header.md └── message.md ├── examples ├── examples.md └── templates │ ├── configuration │ └── raw-keyrings │ │ ├── raw-aes-keyring.md │ │ ├── raw-rsa-keyring-encrypt-with-public-only.md │ │ ├── raw-rsa-keyring-from-encoded-key.md │ │ └── raw-rsa-keyring.md │ └── readme.md ├── framework ├── README.md ├── algorithm-suites.md ├── aws-kms │ ├── aws-kms-discovery-keyring.md │ ├── aws-kms-ecdh-keyring.md │ ├── aws-kms-hierarchical-keyring.md │ ├── aws-kms-key-arn.md │ ├── aws-kms-keyring.md │ ├── aws-kms-mrk-are-unique.md │ ├── aws-kms-mrk-aware-master-key-provider.md │ ├── aws-kms-mrk-aware-master-key.md │ ├── aws-kms-mrk-discovery-keyring.md │ ├── aws-kms-mrk-keyring.md │ ├── aws-kms-mrk-match-for-decrypt.md │ ├── aws-kms-mrk-multi-keyrings.md │ ├── aws-kms-multi-keyrings.md │ └── aws-kms-rsa-keyring.md ├── branch-key-store.md ├── caching-cmm.md ├── cmm-interface.md ├── commitment-policy.md ├── cryptographic-materials-cache.md ├── default-cmm.md ├── key-agreement-schemas.md ├── key-store │ ├── default-key-storage.md │ ├── dynamodb-key-storage.md │ └── key-storage.md ├── keyring-interface.md ├── local-cryptographic-materials-cache.md ├── master-key-interface.md ├── master-key-provider-interface.md ├── multi-keyring.md ├── raw-aes-keyring.md ├── raw-ecdh-keyring.md ├── raw-rsa-keyring.md ├── required-encryption-context-cmm.md ├── storm-tracking-cryptographic-materials-cache.md ├── structures.md ├── synchronized-local-cryptographic-materials-cache.md ├── test-vectors │ ├── README.md │ ├── complete-vectors │ │ ├── README.md │ │ ├── default-cmm.md │ │ ├── encryption-context.md │ │ ├── hierarchy.md │ │ ├── kms-mrk-aware-discovery.md │ │ ├── kms-mrk-aware.md │ │ ├── kms-rsa.md │ │ ├── kms.md │ │ ├── raw-aes.md │ │ ├── raw-rsa.md │ │ └── required-encryption-context-cmm.md │ ├── decryption-manifest.md │ ├── encryption-manifest.md │ ├── esdk-test-vector-enumeration.md │ ├── key-description.md │ ├── keys-manifest.md │ ├── mpl-test-vector-enumeration.md │ └── test-vector-enumeration.md └── transitive-requirements.md ├── proposals ├── 2020-06-26_decrypt-max-header-size-max-body-size │ └── proposal.md └── 2022-10-27_rsa-keyring-v2 │ └── proposal.md ├── tenets.md └── util ├── extract.js ├── install-duvet ├── report.js ├── specification_extract.sh └── test_conditions /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Each line is a file pattern followed by one or more owners. 2 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners 3 | 4 | # Default code owner for everything is our aws-crypto-tools group 5 | * @awslabs/aws-crypto-tools 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | _Issue #, if available:_ 2 | 3 | _Description of changes:_ 4 | 5 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 6 | 7 | # Check any applicable: 8 | 9 | - [ ] Were any files moved? Moving files changes their URL, which breaks all hyperlinks to the files. 10 | -------------------------------------------------------------------------------- /.github/not-grep.toml: -------------------------------------------------------------------------------- 1 | [prefix] 2 | "**/*.md" = """ 3 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 4 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 5 | """ 6 | -------------------------------------------------------------------------------- /.github/workflows/ci_static-analysis.yaml: -------------------------------------------------------------------------------- 1 | # This workflow performs static analysis checks. 2 | name: static analysis 3 | 4 | on: ["pull_request", "push"] 5 | 6 | jobs: 7 | not-grep: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: not-grep 12 | uses: mattsb42-meta/not-grep@1.0.0 13 | prettier: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | - uses: actions/setup-node@v3 18 | - name: install 19 | run: npm install --global prettier 20 | - name: prettify 21 | run: ./ci/prettify.sh check 22 | -------------------------------------------------------------------------------- /.github/workflows/repo-sync.yml: -------------------------------------------------------------------------------- 1 | name: Repo Sync 2 | 3 | on: 4 | workflow_dispatch: # allows triggering this manually through the Actions UI 5 | 6 | jobs: 7 | repo-sync: 8 | name: Repo Sync 9 | environment: repo-sync 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: repo-sync/github-sync@v2 14 | name: Sync repo to branch 15 | with: 16 | source_repo: ${{ secrets.SOURCE_REPO }} 17 | source_branch: master 18 | destination_branch: ${{ secrets.INTERMEDIATE_BRANCH }} 19 | github_token: ${{ secrets.GITHUB_TOKEN }} 20 | - uses: repo-sync/pull-request@v2 21 | name: Create pull request 22 | with: 23 | source_branch: ${{ secrets.INTERMEDIATE_BRANCH }} 24 | destination_branch: master 25 | github_token: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Vim swap files 2 | *~ 3 | *.swp 4 | *.swo 5 | 6 | # OS Artifacts 7 | .DS_Store 8 | 9 | # JetBrains IDE artifacts 10 | .idea/ 11 | venv/ 12 | /.history 13 | /framework/aws-kms/.refcache 14 | .refcache 15 | 16 | # pyenv files 17 | .python-version 18 | 19 | # compliance files are generated on-the-fly 20 | compliance 21 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": false, 3 | "MD032": false, 4 | "MD041": false 5 | } 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # VsCode local history 2 | .history 3 | -------------------------------------------------------------------------------- /.prettierrc.toml: -------------------------------------------------------------------------------- 1 | tabWidth = 2 2 | useTabs = false 3 | printWidth = 90 4 | # Avoid re-formatting existing text. 5 | # All new text SHOULD be formatted with semantic newlines. 6 | # We SHOULD revisit this setting in the future. 7 | proseWrap = "preserve" 8 | # Only use quotes in supported config file formats where necessary. 9 | quoteProps = "as-needed" 10 | # Force all newlines to line-feed-only. 11 | endOfLine = "lf" 12 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | ## Code of Conduct 5 | 6 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 7 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 8 | opensource-codeofconduct@amazon.com with any additional questions or comments. 9 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Contributing Guidelines 5 | 6 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 7 | documentation, we greatly value feedback and contributions from our community. 8 | 9 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 10 | information to effectively respond to your bug report or contribution. 11 | 12 | ## Reporting Bugs/Feature Requests 13 | 14 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 15 | 16 | When filing an issue, please check [existing open](https://github.com/awslabs/aws-encryption-sdk-specification/issues), or [recently closed](https://github.com/awslabs/aws-encryption-sdk-specification/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already 17 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 18 | 19 | - A reproducible test case or series of steps 20 | - The version of our code being used 21 | - Any modifications you've made relevant to the bug 22 | - Anything unusual about your environment or deployment 23 | 24 | ## Contributing via Pull Requests 25 | 26 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 27 | 28 | 1. You are working against the latest source on the _master_ branch. 29 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 30 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 31 | 32 | To send us a pull request, please: 33 | 34 | 1. Fork the repository. 35 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 36 | 3. Ensure local tests pass. 37 | 4. Commit to your fork using clear commit messages. 38 | 5. Send us a pull request, answering any default questions in the pull request interface. 39 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 40 | 41 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 42 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 43 | 44 | ## Finding contributions to work on 45 | 46 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/awslabs/aws-encryption-sdk-specification/labels/help%20wanted) issues is a great place to start. 47 | 48 | ## Code of Conduct 49 | 50 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 51 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 52 | opensource-codeofconduct@amazon.com with any additional questions or comments. 53 | 54 | ## Security issue notifications 55 | 56 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 57 | 58 | ## Licensing 59 | 60 | See the [LICENSE](https://github.com/awslabs/aws-encryption-sdk-specification/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 61 | 62 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 63 | -------------------------------------------------------------------------------- /LICENSE-SAMPLECODE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | software and associated documentation files (the "Software"), to deal in the Software 5 | without restriction, including without limitation the rights to use, copy, modify, 6 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 10 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 11 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 12 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 13 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 14 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /LICENSE-SUMMARY: -------------------------------------------------------------------------------- 1 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | The documentation is made available under the Creative Commons Attribution-ShareAlike 4.0 International License. See the LICENSE file. 4 | 5 | The sample code within this documentation is made available under the MIT-0 license. See the LICENSE-SAMPLECODE file. 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # AWS Encryption SDK Specification 5 | 6 | ## Overview 7 | 8 | This repository contains the AWS Encryption SDK Specification. 9 | The primary goal of this specification is to define a standard, 10 | language independent, description of the AWS Encryption SDK features. 11 | It serves as the source of truth for the features that make up the AWS Encryption SDK 12 | and the details of their behavior. 13 | It is intended to promote consistency and interoperability 14 | across implementations of the AWS Encryption SDK. 15 | This GitHub project is also intended to track issues and feature requests, 16 | and to collect feedback pertaining to the AWS Encryption SDK. 17 | 18 | [Security issue notifications](./CONTRIBUTING.md#security-issue-notifications) 19 | 20 | ### Current Implementations 21 | 22 | Below is the list of current implementation of this specification: 23 | 24 | - [C](https://github.com/aws/aws-encryption-sdk-c) 25 | - [Java](https://github.com/aws/aws-encryption-sdk-java) 26 | - [Python](https://github.com/aws/aws-encryption-sdk-python) 27 | - [CLI](https://github.com/aws/aws-encryption-sdk-cli) 28 | - [Javascript](https://github.com/awslabs/aws-encryption-sdk-javascript) 29 | 30 | ## License Summary 31 | 32 | The documentation is made available under the Creative Commons Attribution-ShareAlike 4.0 International License. See the LICENSE file. 33 | 34 | The sample code within this documentation is made available under the MIT-0 license. See the LICENSE-SAMPLECODE file. 35 | 36 | ## Editing 37 | 38 | We use `prettier` to maintain consistent formatting. 39 | Our CI will stop PRs that do not match our formatting requirements, 40 | but to easily apply them, 41 | run `./ci/prettify.sh write`. 42 | If you want to check them without writing, 43 | run `./ci/prettify.sh check`. 44 | 45 | ## Generate Duvet Reports 46 | 47 | [Duvet](https://github.com/awslabs/aws-encryption-sdk-specification/issues/240) is a tool that can be used to ensure specification is documented alongside code. 48 | 49 | This repo contains helpful scripts for installing and using Duvet with this specification. 50 | 51 | To install Duvet: 52 | 53 | ``` 54 | ./util/install-duvet 55 | ``` 56 | 57 | To generate a report on what portions of this specification are covered in code, use the `report` script. 58 | For example: 59 | 60 | ``` 61 | ./util/report.js 'src/main/**/*.java' 'src/test/**/*.java' 62 | ``` 63 | 64 | ## Extract `compliance` from Specification 65 | 66 | The Specification is written in Markdown. 67 | Our compliance tooling needs RFC formatted text files. 68 | As such, we have a tool that extracts the RFC spec from the Markdown. 69 | 70 | ### RFC Scope 71 | 72 | We do not include every Markdown file in the RFC spec; 73 | Nor do we include all sections of the Markdown files 74 | (i.e. we exclude legacy, changes, etc.). 75 | 76 | The directories in scope for RFC specifications are those listed 77 | in `util/specification_extract.sh`. 78 | 79 | ### Running `extract` 80 | 81 | #### Running on A change 82 | 83 | If you have changed any Markdown in scope for compliance, you MUST run the extract utility. 84 | There are two ways of doing this. If you have changed only one file, you may run `extract` against just that file. 85 | 86 | ``` 87 | ./util/extract.js PATH_TO_CHANGED_MARKEDOWN 88 | ``` 89 | 90 | For example, if ONLY the Default CMM Markdown was updated, we would run: 91 | 92 | ``` 93 | ./util/extract.js framework/default-cmm.md 94 | ``` 95 | 96 | #### Running on all 97 | 98 | Alternatively, the entire specification may be extracted at once. Run: 99 | 100 | ``` 101 | ./util/specification_extract.sh 102 | ``` 103 | 104 | ### Installing dependencies 105 | 106 | The utility/script `util/extract.js` depends on four run 107 | times: `node`, `python`, `ruby`, and `rust` 108 | (No, this is not ideal, but Crypto Tools is pushing the "spec to code" boundary; 109 | we are ahead of the tooling). 110 | 111 | #### Set Up Python & `xml2rfc` 112 | 113 | Follow [AWS Crypto Tools Getting Started with Python instructions](https://github.com/aws/crypto-tools/blob/master/getting-started/python/README.md#local-development-setup) to install `pyenv`. 114 | 115 | Then, in this repository, run `pyenv local 3.9.7; pyenv exec python -m pip install xml2rfc==3.5.0 markupsafe==2.0.1`. 116 | 117 | #### Set up `kramdown-rfc2629` 118 | 119 | This is the Ruby dependency. Unfortunately, we have not figured out 120 | a good way of installing this, so we do a bad way: 121 | 122 | ``` 123 | sudo gem install kramdown-rfc2629 124 | ``` 125 | 126 | #### Node 127 | 128 | Follow 129 | [Installing Node.js with `nvm` macOS by Daniel Schildt](https://gist.github.com/d2s/372b5943bce17b964a79) 130 | to get `nvm` and `node` working. 131 | 132 | #### Rust 133 | 134 | Installing Duvet will install rust. 135 | -------------------------------------------------------------------------------- /VERSIONING.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Definitions 5 | 6 | ## Conventions used in this document 7 | 8 | The key words 9 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 10 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 11 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 12 | 13 | ## Specification Document 14 | 15 | A single document that defines a single feature. 16 | Ex: [Keyring interface](./framework/keyring-interface.md). 17 | 18 | ## Specification 19 | 20 | The collection of all specification documents contained within this repository. 21 | 22 | # Versioning Policy 23 | 24 | We follow [Semantic Versioning](https://semver.org/). 25 | 26 | Given a version number MAJOR.MINOR.PATCH, increment the: 27 | 28 | - MAJOR version when you make incompatible API changes, 29 | - MINOR version when you add functionality in a backwards compatible manner, and 30 | - PATCH version when you make backwards compatible bug fixes. 31 | 32 | ## Beta Releases 33 | 34 | Versions with MAJOR version 0 (0.MINOR.PATCH) are beta releases. 35 | Beta releases MAY introduce MAJOR changes in a MINOR version increment. 36 | 37 | # Overall 38 | 39 | The overall specification, 40 | defined as the collection of all specification documents, 41 | is not versioned. 42 | 43 | # Specification Documents 44 | 45 | Each specification document MUST define its version. 46 | This version only applies to the contents of that document. 47 | 48 | ## Changelogs 49 | 50 | Each specification document MUST contain a changelog 51 | that records the changes made to each version of the document. 52 | 53 | ## Implementations 54 | 55 | Each specification document SHOULD maintain a listing of 56 | implementations that have been known to comply with 57 | a version of that specification document. 58 | Each implementation listing MUST identify the language 59 | as well as provide a link to a file in the implementation 60 | that states what version of the specification document 61 | it implements. 62 | 63 | NOTE: 64 | The presence of a reference to an implementation does not imply that 65 | every listed implementation complies with the current version of 66 | the specification document that contains that reference. 67 | -------------------------------------------------------------------------------- /changes/2020-06-04_how-to-fail-with-keyrings/background.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # How to fail with Keyrings in the AWS Encryption SDK 5 | 6 | # Definitions 7 | 8 | ## Conventions used in this document 9 | 10 | The key words 11 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 12 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 13 | in this document are to be interpreted as described in 14 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 15 | 16 | # Background 17 | 18 | We lack a consistent definition both of what it means to fail 19 | and how different parts of the AWS Encryption SDK (ESDK) framework handle 20 | different failures. 21 | Without this consistent definition, 22 | implementations are left to 23 | "whatever the dev thought was a good idea at the time", 24 | creating inconsistencies across implementations. 25 | 26 | # Requirements 27 | 28 | In order to resolve these inconsistencies, 29 | we need to define what kinds of failure modes we allow, 30 | what causes them, 31 | and how the ESDK framework components handle them. 32 | 33 | # Success Measurements 34 | 35 | We will know we are succeeding when we have consensus on 36 | the definition of when keyrings fail, 37 | what causes those failures, 38 | and how ESDK framework components handle those failures. 39 | 40 | # Out of Scope 41 | 42 | - The specifics of how ESDK framework components 43 | communicate failure information between themselves 44 | is out of scope for this document. 45 | That will be addressed separately once we have 46 | consensus on this document. 47 | 48 | - The specific nature of _how_ ESDK framework components indicate failure 49 | is out of scope for this document. 50 | That will depend on the best practices for each language. 51 | 52 | - We need to define detailed decryption contracts 53 | (defined in [Issues and Alternatives](#issues-and-alternatives)) 54 | for each keyring defined in the ESDK specification. 55 | This will be addressed separately once we have 56 | consensus on this document. 57 | 58 | - A mechanism to interrogate a keyring to determine 59 | the requirements of its decryption contract 60 | (defined in [Issues and Alternatives](#issues-and-alternatives)) 61 | is out of scope for this document. 62 | We should pursue this once decryption contracts are defined 63 | for each keyring. 64 | 65 | # Issues and Alternatives 66 | 67 | ## Issue 0 : What does a keyring do? 68 | 69 | In order to define when a keyring fails, 70 | we must first clearly define what a keyring does. 71 | When a keyring encrypts a data key, 72 | it creates one or more artifacts that define 73 | a set of requirements that MUST be met 74 | in order to use that artifact 75 | to obtain the data key. 76 | We call this set of requirements the "decryption contract". 77 | In order to obtain the data key from the artifact, 78 | a keyring MUST "satisfy" the decryption contract. 79 | 80 | For example, some decryption contracts for keyrings include: 81 | 82 | - Raw RSA keyring 83 | 84 | - The keyring MUST have access to the private wrapping key. 85 | 86 | - Raw AES keyring 87 | 88 | - The keyring MUST have access to the symmetric wrapping key. 89 | - The encryption context MUST exactly match 90 | the encryption context used on encrypt. 91 | 92 | - NOTE: In compliant implementations this is a MUST, 93 | but mathematically this is a SHOULD 94 | because it is possible to create a keyring 95 | that ignores this clause in the decryption contract 96 | by using AES-CTR rather than AES-GCM. 97 | 98 | - AWS KMS keyring (single CMK) 99 | 100 | - The AWS KMS client MUST be configured with credentials for 101 | an AWS principal that will pass a `kms:Decrypt` authorization check 102 | for the encrypted data key. 103 | - The encryption context MUST exactly match 104 | the encryption context used on encrypt. 105 | 106 | - Multi-keyring: 107 | 108 | - Satisfying any member keyring's decryption contract 109 | MUST be sufficient to satisfy 110 | the multi-keyring's decryption contract. 111 | 112 | ## Issue 1 : When MUST a keyring fail? 113 | 114 | - On encrypt, 115 | if a keyring is unable or unwilling to create an artifact or artifacts 116 | that can be used to satisfy its decryption contract, 117 | the keyring MUST fail. 118 | 119 | - On decrypt, 120 | if a keyring is unable or unwilling to satisfy 121 | the artifact's decryption contract, 122 | the keyring MUST fail. 123 | 124 | ## Issue 2 : What happens when a keyring fails? 125 | 126 | When a keyring fails, 127 | it MUST communicate 128 | information about the cause of that failure 129 | to the component that called the keyring. 130 | 131 | ## Issue 3 : What implications does this have to existing keyring specifications? 132 | 133 | In addition to introducing the concept of decryption contracts 134 | and defining each keyring's decryption contract, 135 | this change affects the following keyring specifications. 136 | 137 | - Keyring interface : 138 | The keyring interface defines no-op behavior as 139 | "output[ing] the encryption/decryption materials unmodified". 140 | This needs to be modified to frame this behavior as a failure 141 | and state that encryption/decryption materials MUST NOT be modified 142 | when a keyring fails. 143 | 144 | - _This also affects all keyring specifications._ 145 | 146 | - Multi-keyring : 147 | The multi-keyring behavior is defined in a way that assumes that 148 | different kinds of failure exist. 149 | This is in line with how we had previously thought about failure, 150 | but is not in line with this new model. 151 | 152 | - On encrypt, if _any_ child keyring fails, 153 | the multi-keyring MUST fail. 154 | - On decrypt, if _all_ child keyrings fail, 155 | the multi-keyring MUST fail. 156 | 157 | # One-Way Doors 158 | 159 | Once we define the decryption contract for a keyring, 160 | that contract MUST NOT change. 161 | 162 | # Security Considerations 163 | 164 | If the decryption contract of any existing keyrings 165 | does not match the existing published implementations, 166 | that will have security implications for anyone using those keyrings. 167 | -------------------------------------------------------------------------------- /changes/2020-06-09_wrapping-key-identifiers/change.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Clarify Wrapping Key Identifiers 5 | 6 | ## Affected Features 7 | 8 | This serves as a reference of all features that this change affects. 9 | 10 | | Feature | 11 | | --------------------------------------------------------------------------------------------------- | 12 | | [Encrypted Data Key](../../framework/structures.md#encrypted-data-key) | 13 | | [AWS KMS Keyring](../../framework/aws-kms/aws-kms-keyring.md) | 14 | | [Raw AES Keyring](../../framework/raw-aes-keyring.md) | 15 | | [Raw RSA Keyring](../../framework/raw-rsa-keyring.md) | 16 | | [Keyring Decryption Contract](https://github.com/awslabs/aws-encryption-sdk-specification/pull/131) | 17 | 18 | ## Affected Specifications 19 | 20 | This serves as a reference of all specification documents that this change affects. 21 | 22 | | Specification | 23 | | ------------------------------------------------------------- | 24 | | [Structures](../../framework/structures.md) | 25 | | [Keyring Interface](../../framework/keyring-interface.md) | 26 | | [AWS KMS Keyring](../../framework/aws-kms/aws-kms-keyring.md) | 27 | | [Raw AES Keyring](../../framework/raw-aes-keyring.md) | 28 | | [Raw RSA Keyring](../../framework/raw-rsa-keyring.md) | 29 | 30 | ## Affected Implementations 31 | 32 | The scope of this change only affects the specification. 33 | Follow-up changes that define 34 | whether implementations expose these concepts 35 | MAY affect implementations. 36 | 37 | ## Definitions 38 | 39 | ### Conventions used in this document 40 | 41 | The key words 42 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 43 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 44 | in this document are to be interpreted as described in 45 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 46 | 47 | ## Summary 48 | 49 | We have referenced several terms throughout various specification documents 50 | that are never defined: 51 | "key namespace", 52 | "key name", 53 | "key provider ID", 54 | and "key provider info". 55 | This change defines each of these terms 56 | and describes their relationships to each other 57 | and the keyrings they represent. 58 | 59 | ## Out of Scope 60 | 61 | - Whether, or how, each keyring exposes any of these values at runtime is out of scope. 62 | 63 | - Specific values for these terms for any specific keyring is out of scope. 64 | 65 | ## Motivation 66 | 67 | Various specification documents reference 68 | "key namespace", 69 | "key name", 70 | "key provider ID", 71 | and "key provider info", 72 | but we never define what these terms mean 73 | or how they relate to each other. 74 | 75 | In order to ensure the specification documents accurately describe keyring behavior, 76 | we need to define all terms that they use. 77 | 78 | ## Drawbacks 79 | 80 | This change SHOULD NOT introduce any drawbacks. 81 | It is identifying and describing 82 | terms that already exist 83 | and the existing relationship between them. 84 | 85 | ## Security Implications 86 | 87 | This change SHOULD NOT have any security implications. 88 | 89 | ## Operational Implications 90 | 91 | This change SHOULD NOT have any operational implications. 92 | 93 | ## Guide-level Explanation 94 | 95 | Key namespace and key name are configuration values that determine the behavior of a keyring. 96 | 97 | Key provider ID and key provider info are values that identify the keyring configuration 98 | that can fulfill the keyring's decryption contract. 99 | The keyring attaches these values to a data key ciphertext to form an encrypted data key. 100 | 101 | ## Reference-level Explanation 102 | 103 | "Key namespace", "key name", "key provider ID", and "key provider info" 104 | are all concepts that identify a wrapping key. 105 | 106 | ### key namespace 107 | 108 | A configuration value for a keyring 109 | that identifies the grouping or categorization 110 | for the wrapping keys that keyring can access. 111 | 112 | The key namespace MUST be a string value. 113 | 114 | ### key name 115 | 116 | A configuration value for a keyring 117 | that identifies a single wrapping key 118 | within a key namespace. 119 | 120 | The key name MUST be a string value. 121 | 122 | ### key provider ID 123 | 124 | An output value returned by a keyring on encrypt 125 | as part of an encrypted data key structure 126 | that identifies the grouping or categorization 127 | for a keyring that can fulfill this decryption contract. 128 | 129 | The key provider ID MUST be a binary value 130 | and SHOULD be equal to a UTF-8 encoding of the key namespace. 131 | 132 | ### key provider info 133 | 134 | An output value returned by a keyring on encrypt 135 | as part of an encrypted data key structure 136 | that provides necessary information for a keyring 137 | to fulfill this decryption contract. 138 | 139 | The key provider info MUST be a binary value 140 | and SHOULD be equal to a UTF-8 encoding of the key name. 141 | 142 | One example of a keyring where the key name and key provider info can differ 143 | is the AWS KMS keyring. 144 | This keyring uses its key name to identify the desired CMK in its call to AWS KMS. 145 | However, the key provider info that this keyring writes is 146 | the CMK identifier that AWS KMS includes in its response. 147 | If the key name is a CMK ARN, these two values are identical 148 | because this response value is always the CMK ARN of the CMK that AWS KMS used. 149 | However, if the key name is some other valid CMK identifier, 150 | such as an alias, 151 | then they are different. 152 | -------------------------------------------------------------------------------- /changes/2020-06-16_required-examples/change.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Define Required Examples 5 | 6 | ## Affected Specifications 7 | 8 | This serves as a reference of all specification documents that this change affects. 9 | 10 | | Specification | 11 | | ----------------------------------------------------- | 12 | | [examples](../../examples/examples.md) | 13 | | [examples readme](../../examples/templates/readme.md) | 14 | 15 | ## Affected Implementations 16 | 17 | This serves as a reference for all implementations that this change affects. 18 | 19 | | Language | Repository | 20 | | ---------- | ------------------------------------------------------------------------------------- | 21 | | Python | [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python) | 22 | | Java | [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java) | 23 | | C | [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c) | 24 | | Javascript | [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript) | 25 | 26 | ## Definitions 27 | 28 | ### Conventions used in this document 29 | 30 | The key words 31 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 32 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 33 | in this document are to be interpreted as described in 34 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 35 | 36 | ## Summary 37 | 38 | This document defines the examples that each implementation MUST include. 39 | 40 | ## Out of Scope 41 | 42 | The specific implementations details for each example 43 | are out of scope for this document. 44 | The template document for each example contains those details. 45 | 46 | ## Motivation 47 | 48 | The primary motivations for requiring examples include: 49 | 50 | - Providing guidance to AWS Encryption SDK customers. 51 | - Facilitating documentation and interoperability. 52 | - Encouraging AWS Encryption SDK developers 53 | to work backwards from the caller experience 54 | to verify that APIs and components 55 | provide the intended functionality, 56 | clarity, and ease of use. 57 | - Demonstrating that all implementations 58 | can be used to solve the same problems. 59 | 60 | ## Drawbacks 61 | 62 | Requiring each implementation to include many examples 63 | increases the level of effort to create each implementation. 64 | We believe that the value to customers of 65 | improving the usability of APIs 66 | and providing guidance on how to use them 67 | justifies this cost. 68 | 69 | ## Security Implications 70 | 71 | We MUST assume that any example will be used in production. 72 | Because of this, every example MUST only contain logic 73 | that is reasonable for production use 74 | unless explicitly identified otherwise. 75 | 76 | ## Operational Implications 77 | 78 | Each implementation MUST include all examples 79 | in its continuous integration testing. 80 | 81 | ## Guide-level Explanation 82 | 83 | Every implementation MUST include an example 84 | for each required use-case. 85 | These examples MUST be tested as part of 86 | the implementation's continuous integration testing. 87 | 88 | ## Reference-level Explanation 89 | 90 | - Every example MUST be tested 91 | as part of the implementation's continuous integration testing. 92 | - Every example MUST be independent and complete. 93 | - Every example SHOULD follow a consistent layout and framing. 94 | 95 | - ex: Consistent function name and input parameters across examples. 96 | 97 | - Every example MUST only contain logic that is reasonable for production use. 98 | - If an example MUST contain logic that is not reasonable for production use, 99 | it MUST include clear comments that 100 | MUST identify that logic as not fit for production use, 101 | SHOULD explain why it is not fit for production use, 102 | and MUST instruct the reader what they SHOULD do instead. 103 | 104 | - ex: Raw keyring examples generate wrapping keys as part of the example. 105 | These examples MUST contain guidance that 106 | in production those keys SHOULD be managed by an HSM. 107 | -------------------------------------------------------------------------------- /changes/2020-07-13_detect-base64-encoded-messages/change.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Detect Base64-encoded Messages 5 | 6 | ## Affected Features 7 | 8 | This serves as a reference of all features that this change affects. 9 | 10 | | Feature | 11 | | --------------------------------------- | 12 | | [Decrypt](../../client-apis/decrypt.md) | 13 | 14 | ## Affected Specifications 15 | 16 | This serves as a reference of all specification documents that this change affects. 17 | 18 | | Specification | 19 | | --------------------------------------- | 20 | | [Decrypt](../../client-apis/decrypt.md) | 21 | 22 | ## Affected Implementations 23 | 24 | This serves as a reference for all implementations that this change affects. 25 | 26 | | Language | Repository | 27 | | ---------- | ------------------------------------------------------------------------------------- | 28 | | C | [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c) | 29 | | Java | [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java) | 30 | | Javascript | [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript) | 31 | | Python | [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python) | 32 | 33 | ## Definitions 34 | 35 | ### Conventions used in this document 36 | 37 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 38 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 39 | 40 | ## Summary 41 | 42 | When a decryption attempt is made on the Base64-encoding of a valid message, 43 | implementations SHOULD detect this and provide a more specific error message. 44 | 45 | ## Motivation 46 | 47 | The message format is a binary format 48 | but users commonly attempt to decrypt the Base64 encoding of this data. 49 | Because the first two bytes of the message format have a very limited set of possible values 50 | (currently they are in fact fixed), 51 | the first two bytes of the Base64 encoding of a valid message are also simple to recognize. 52 | 53 | ## Drawbacks 54 | 55 | If the version value ever advances beyond the hex value `40`, 56 | it will not be possible to catch this error for all supported versions 57 | since `41` would then conflict with the Base64-encoded value for `1`. 58 | This is acceptable given it is a best-effort guard, 59 | and also extremely unlikely 60 | given how rarely we intended to change the version. 61 | 62 | ## Security Implications 63 | 64 | This change SHOULD NOT have any security implications. 65 | 66 | ## Operational Implications 67 | 68 | This change should have positive operational impact 69 | because it removes ambiguity on a common failure mode, 70 | reducing potential for customer confusion 71 | and increasing the likelihood that customers can 72 | diagnose this root cause without needing to contact us. 73 | 74 | ## Guide-level Explanation 75 | 76 | When a decryption attempt is made on the Base64-encoding of a valid message, 77 | implementations SHOULD detect this and provide a more specific error message on a best-effort basis. 78 | 79 | ## Reference-level Explanation 80 | 81 | Implementations SHOULD detect the first two bytes of the Base64 encoding of any supported message [versions](../data-format/message-header.md#version-1) 82 | and [types](../data-format/message-header.md#type) 83 | and fail with a more specific error message. 84 | In particular, the hex values to detect for the current set of versions and types are: 85 | 86 | | Version and type (hex) | Base64 encoding (ascii) | Base64 encoding (hex) | 87 | | ---------------------- | ----------------------- | --------------------- | 88 | | 01 80 | A Y ... | 41 59 ... | 89 | 90 | Note that the bytes that follow the initial two in the Base64 encoding 91 | partially depend on subsequent bytes in the binary message format 92 | and hence are not as predictable. 93 | -------------------------------------------------------------------------------- /changes/2020-07-14_multi-keyring-require-generation/change.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Require Generation in the Multi-Keyring 5 | 6 | ## Affected Features 7 | 8 | This serves as a reference of all features that this change affects. 9 | 10 | | Feature | 11 | | ------------------------------------------------------------------------------------------------- | 12 | | [Multi-Keyring](../../framework/multi-keyring.md) | 13 | | [Multi-Keyring Generator](https://github.com/awslabs/aws-encryption-sdk-specification/issues/114) | 14 | 15 | ## Affected Specifications 16 | 17 | This serves as a reference of all specification documents that this change affects. 18 | 19 | | Specification | 20 | | ------------------------------------------------- | 21 | | [Multi-Keyring](../../framework/multi-keyring.md) | 22 | 23 | ## Affected Implementations 24 | 25 | This serves as a reference for all implementations that this change affects. 26 | 27 | | Language | Repository | 28 | | ---------- | ------------------------------------------------------------------------------------- | 29 | | C | [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c) | 30 | | Javascript | [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript) | 31 | 32 | This change additionally affects the unreleased AWS KMS keyring implementations for Java and Python. 33 | 34 | ## Definitions 35 | 36 | ### Conventions used in this document 37 | 38 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 39 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 40 | 41 | ## Summary 42 | 43 | The multi-keyring has a clearly configured intent of which keyring SHOULD be used to generate the data key, 44 | but this is not actually enforced during the encryption operation. 45 | This change strengthens the requirements on multi-keyrings such that if a generator is configured, 46 | it MUST generate the data key. 47 | 48 | ## Out of Scope 49 | 50 | If a multi-keyring is configured with another multi-keyring as its generator, 51 | and this second multi-keyring has no generator, 52 | the outer multi-keyring cannot ever successfully complete an OnEncrypt operation. 53 | This is one of several examples of keyring configurations 54 | that cannot satisfy the requirements of an operation. 55 | Detecting at keyring configuration time that encryption/decryption will always fail 56 | because keyrings are not capable of meeting their requirements 57 | is [tracked separately](https://github.com/awslabs/aws-encryption-sdk-specification/issues/144). 58 | 59 | ## Motivation 60 | 61 | If we do not make a guarantee that the generator will generate, 62 | then its usefulness is limited. 63 | Customers might have a compliance requirement that all data keys MUST be generated by a specific HSM, 64 | or might want to lock down true least-privilege permissions for their AWS KMS key policies. 65 | Under the current model, 66 | customers have to be very careful to make sure that they know 67 | exactly where and how a given multi-keyring configuration is being used 68 | rather than being certain that it will always do the same thing no matter what. 69 | 70 | ## Drawbacks 71 | 72 | This is a breaking change, 73 | since existing multi-keyring configurations 74 | can be used in multiple contexts, 75 | and data key generation is not tightly controlled. 76 | We judge this to be the right trade-off 77 | between security and usability. 78 | 79 | ## Security Implications 80 | 81 | Removing this flexibility might help identify potential security issues. 82 | For example, when upgrading their version of the ESDK, customers might discover 83 | that data keys are not being generated as intended. 84 | Correcting this will in turn provide the opportunity 85 | to improve their security postures 86 | through improvements such as scoping down permissions. 87 | 88 | ## Operational Implications 89 | 90 | Customers that are currently using a single multi-keyring instance 91 | in multiple contexts with inconsistent data key generation patterns 92 | will encounter errors when upgrading. 93 | This might lead to an increase in support requests, 94 | but SHOULD also reduce troubleshooting requests 95 | related to unexpected behaviour around data key generation, 96 | or unexpected permissions errors due to the same. 97 | 98 | ## Guide-level/Reference-level Explanation 99 | 100 | The description of OnEncrypt for the multi-keyring 101 | will be changed to read as follows: 102 | 103 | If this keyring has a generator keyring, 104 | this keyring MUST first generate a plaintext data key using the generator keyring: 105 | 106 | - If the input encryption materials already include a plaintext data key, 107 | OnEncrypt MUST fail. 108 | - This keyring MUST first call the generator keyring's OnEncrypt 109 | using the input encryption materials as input. 110 | - If the generator keyring fails OnEncrypt, 111 | this OnEncrypt MUST also fail. 112 | - If the generator keyring returns encryption materials missing a plaintext data key, 113 | OnEncrypt MUST fail. 114 | -------------------------------------------------------------------------------- /changes/2020-07-15_clarify-caching-cmm-init-params/change.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Clarify Caching Cryptographic Materials Manager Initialization Parameters 5 | 6 | ## Affected Features 7 | 8 | | Feature | 9 | | ------------------------------------------------------------------------- | 10 | | [Caching Cryptographic Materials Manager](../../framework/caching-cmm.md) | 11 | 12 | ## Affected Specifications 13 | 14 | | Specification | 15 | | ------------------------------------------------------------------------- | 16 | | [Caching Cryptographic Materials Manager](../../framework/caching-cmm.md) | 17 | 18 | ## Affected Implementations 19 | 20 | | Language | Repository | 21 | | ---------- | ------------------------------------------------------------------------------------- | 22 | | C | [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c) | 23 | | Java | [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java) | 24 | | JavaScript | [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript) | 25 | | Python | [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python) | 26 | 27 | ## Definitions 28 | 29 | ### Conventions used in this document 30 | 31 | The key words 32 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 33 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 34 | in this document are to be interpreted as described in 35 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 36 | 37 | ## Summary 38 | 39 | Upon initialization, 40 | the [caching Cryptographic Materials Manager (caching CMM)](../../framework/caching-cmm.md) MUST define 41 | an underlying CMM, 42 | an underlying Cryptographic Materials Cache (CMC), 43 | and a [time-to-live (TTL)](../../framework/caching-cmm.md) for cache entries. 44 | This change clarifies that the caller MUST provide these parameters. 45 | 46 | ## Out of Scope 47 | 48 | - Changing the shape of any CMC APIs is out of scope. 49 | - Changing the shape of the CMM interface is out of scope. 50 | 51 | ## Motivation 52 | 53 | Before this change, 54 | the [caching CMM](../../framework/caching-cmm.md) specification 55 | lists several properties that the caching CMM MUST define upon initialization. 56 | Among these, 57 | we intend for the caller to provide 58 | the [underlying CMC](../../framework/caching-cmm.md#underlying-cryptographic-materials-cache), 59 | the [underlying CMM](../../framework/caching-cmm.md#underlying-cryptographic-materials-manager), 60 | and the [TTL](../../framework/caching-cmm.md#cache-limit-ttl); 61 | but the specification does not state that intent. 62 | This change adds this missing intent. 63 | 64 | ## Security Implications 65 | 66 | This change SHOULD NOT have any security implications. 67 | 68 | ## Operational Implications 69 | 70 | This change can potentially break any customer using an AWS Encryption SDK implementation 71 | that does not require the user to provide the TTL value upon caching CMM initialization. 72 | However, all existing implementations require the user to provide the TTL value, 73 | so in practice this is not an issue. 74 | 75 | ## Guide- and Reference-level Explanation 76 | 77 | When initializing a caching CMM, the caller MUST provide 78 | an [underlying CMC](../../framework/caching-cmm.md#underlying-cryptographic-materials-cache) 79 | and a [TTL](../../framework/caching-cmm.md#cache-limit-ttl). 80 | 81 | The caller MUST either provide 82 | an [underlying CMM](../../framework/caching-cmm.md#underlying-cryptographic-materials-manager) 83 | or a [keyring](../../framework/keyring-interface.md). 84 | If the caller provides a keyring, 85 | then the caching CMM MUST set its underlying CMM 86 | to a [default CMM](../../framework/default-cmm.md) initialized with the keyring. 87 | -------------------------------------------------------------------------------- /changes/2020-07-15_encryption-context-reserved-prefix/change.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Encryption Context Reserved Prefix 5 | 6 | ## Affected Features 7 | 8 | This serves as a reference of all features that this change affects. 9 | 10 | | Feature | 11 | | ------------------------------------------------------------------------------------------------------------------ | 12 | | [Structures](../../framework/structures.md) | 13 | | [Default CMM](../../framework/default-cmm.md) | 14 | | [Encrypt](../../client-apis/encrypt.md) | 15 | | [Define encryption context reserved prefix](https://github.com/awslabs/aws-encryption-sdk-specification/issues/23) | 16 | 17 | ## Affected Specifications 18 | 19 | This serves as a reference of all specification documents that this change affects. 20 | 21 | | Specification | 22 | | --------------------------------------------- | 23 | | [Structures](../../framework/structures.md) | 24 | | [Default CMM](../../framework/default-cmm.md) | 25 | | [Encrypt](../../client-apis/encrypt.md) | 26 | 27 | ## Affected Implementations 28 | 29 | This serves as a reference for all implementations that this change affects. 30 | 31 | | Language | Repository | 32 | | ---------- | ------------------------------------------------------------------------------------- | 33 | | Python | [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python) | 34 | | Java | [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java) | 35 | | C | [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c) | 36 | | Javascript | [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript) | 37 | 38 | ## Definitions 39 | 40 | ### Conventions used in this document 41 | 42 | The key words 43 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 44 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 45 | in this document are to be interpreted as described in 46 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 47 | 48 | ## Summary 49 | 50 | The specification currently states that the encryption context 51 | MUST reserve the `aws-crypto-public-key` key for use by the AWS Encryption SDK (ESDK) 52 | and SHOULD reserve any key with the prefix `aws`. 53 | We will replace these two requirements with a statement that the encryption context 54 | MUST reserve any key with the prefix `aws-crypto-`. 55 | 56 | We will also relocate this statement to apply to the encryption context passed to encrypt, 57 | rather than on all encryption context values. 58 | 59 | ## Out of Scope 60 | 61 | It is possible that an existing encryption context used as input to encrypt 62 | will be broken by this change. 63 | Designing a migration approach for affected customers 64 | is out of scope for this document. 65 | 66 | ## Motivation 67 | 68 | The current statement using "SHOULD" is too weak to be of any use. 69 | Some customers could be providing encryption contexts 70 | with keys using the `aws` prefix, 71 | and in fact this is relatively likely 72 | since the context of many uses of the ESDK 73 | involves one or more relevant values related to AWS services. 74 | This means if any future versions of CMMs packaged with the ESDK 75 | choose to add additional internal keys to the encryption context, 76 | they could be a breaking change. 77 | 78 | In addition, stating that the encryption context structure itself 79 | MUST reserve any set of keys 80 | is questionable. 81 | Interpreted literally, this leads to a contradiction 82 | since the [Default CMM](../../framework/default-cmm.md) itself adds a key with the reserved prefix. 83 | Therefore, it is clearer to specify this 84 | as a restriction on the input to the decrypt operation. 85 | This still allows any [CMM](../../framework/cmm-interface.md) to use the reserved scope. 86 | 87 | ## Drawbacks 88 | 89 | Even reserving the less general `aws-crypto-` prefix 90 | is still a breaking change, 91 | since it is currently possible for customers 92 | to include keys beginning with this prefix. 93 | This is much less likely to actually break any customers 94 | compared to any variation of the `aws` prefix, however. 95 | 96 | ## Security Implications 97 | 98 | By itself this change SHOULD NOT have any security implications. 99 | 100 | ## Operational Implications 101 | 102 | There is still a very slight chance 103 | this change will break an existing use case. 104 | This change will be released under a new major version of each implementation, 105 | and it will at least be possible, if difficult, 106 | for any affected customers to migrate to using a different key. 107 | 108 | ## Guide-level/Reference-level Explanation 109 | 110 | The last two statements in the specification of the [encryption context structure](../../framework/structures.md#encryption-context) 111 | referring to reserved keys SHALL be removed. 112 | 113 | The encrypt operation specification will be changed to fail 114 | if provided an encryption context containing a key 115 | that begins with the reserved prefix `aws-crypto-`. 116 | 117 | Finally, the default CMM Get Encryption Materials operation 118 | will specify that if the encryption context included in the request 119 | already contains the `aws-crypto-public-key` key 120 | it MUST fail. 121 | This is to ensure this key is not overwritten 122 | in any uses of the CMM that do not go through the top-level encrypt operation. 123 | -------------------------------------------------------------------------------- /changes/2020-07-15_specify-behavior-for-raw-aes-keyring-for-invalid-EC/change.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Specify behavior for Raw AES Keyring for invalid input encryption context 5 | 6 | ## Affected Features 7 | 8 | This serves as a reference of all features that this change affects. 9 | 10 | | Feature | 11 | | --------------------------------------------------------------------------------------------------------------------------------------------------------- | 12 | | [Raw AES Keyring](https://github.com/awslabs/aws-encryption-sdk-specification/blob/623992d999db0b309d8a8adbd664f0d72feee813/framework/raw-aes-keyring.md) | 13 | 14 | ## Affected Specifications 15 | 16 | This serves as a reference of all specification documents that this change affects. 17 | 18 | | Specification | 19 | | --------------------------------------------------------------------------------------------------------------------------------------------------------- | 20 | | [Raw AES Keyring](https://github.com/awslabs/aws-encryption-sdk-specification/blob/623992d999db0b309d8a8adbd664f0d72feee813/framework/raw-aes-keyring.md) | 21 | 22 | ## Affected Implementations 23 | 24 | This serves as a reference for all implementations that this change affects. 25 | 26 | | Language | Repository | 27 | | ---------- | ------------------------------------------------------------------------------------- | 28 | | C | [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c) | 29 | | Javascript | [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript) | 30 | 31 | ## Definitions 32 | 33 | "serialize", "serialization", and "serializability" all refer to 34 | [message header serialization of AAD key value pairs](../../data-format/message-header.md#key-value-pairs) 35 | 36 | ### Conventions used in this document 37 | 38 | The key words 39 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 40 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 41 | in this document are to be interpreted as described in 42 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 43 | 44 | ## Summary 45 | 46 | The Raw AES Keyring must serialize the encryption context for use as AAD. 47 | The specification did not describe how the keyring should behave when given an unserializable encryption context. 48 | 49 | With this change, the Raw AES Keyring MUST attempt to serialize the encryption context, 50 | prior to attempting encryption/decryption. 51 | If the Raw AES Keyring cannot serialize the encryption context, it MUST fail. 52 | 53 | ## Out of Scope 54 | 55 | - All keyrings aside from the Raw AES Keyring 56 | - The encryption context serialization format 57 | 58 | ## Motivation 59 | 60 | The C and Javascript implementations of the Raw AES Keyring check for serializability at different points in OnDecrypt. 61 | This has the potential to lead to different behaviors under specific circumstances. 62 | 63 | ## Drawbacks 64 | 65 | Since we attempt to serialize the encryption context before attempting any decryption, 66 | the Raw AES Keyring may attempt to serialize an encryption context in cases where no EDK matches the keyring. 67 | This scenario results in slower operation when compared to the current Javascript implementation, 68 | which only checks serializability when attempting to decrypt an EDK. 69 | 70 | ## Security Implications 71 | 72 | This change SHOULD NOT have any security implications. 73 | 74 | ## Operational Implications 75 | 76 | This change will improve behavioral consistency between Raw AES Keyring implications. 77 | This should improve the customer experience and reduce support engagements. 78 | 79 | ## Guide-level Explanation 80 | 81 | Serialize the encryption/decryption materials' encryption context before attempting encryption/decryption. 82 | If serialization fails, the OnEncrypt/OnDecrypt operation MUST fail. 83 | When encrypting/decryption the datakey, use the already serialized encryption context as the AAD. 84 | 85 | ## Reference-level Explanation 86 | 87 | ### OnEncrypt 88 | 89 | Before encrypting the plaintext datakey, OnEncrypt MUST attempt to serialize the encryption context. 90 | If serialization fails, OnEncrypt MUST fail. 91 | This is not a new change, but is more explicit now. 92 | 93 | ### OnDecrypt 94 | 95 | Before iterating through the list of EDKs, OnDecrypt MUST attempt to serialize the encryption context. 96 | If serialization fails, OnDecrypt MUST fail. 97 | If serialization succeeds, 98 | the resulting serialized encryption context MUST be used as additional authenticated 99 | data (AAD) for any AES decrypt operations the keyring attempts. 100 | -------------------------------------------------------------------------------- /changes/2020-07-20_put-cache-entry-returns-nothing/change.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Return Nothing from Put Cache Entry in Cryptographic Materials Cache 5 | 6 | ## Affected Features 7 | 8 | | Feature | 9 | | ------------------------------------------------------------------------------------------- | 10 | | [Cryptographic Materials Cache Interface](../../framework/cryptographic-materials-cache.md) | 11 | 12 | ## Affected Specifications 13 | 14 | | Specification | 15 | | ------------------------------------------------------------------------------------------- | 16 | | [Cryptographic Materials Cache Interface](../../framework/cryptographic-materials-cache.md) | 17 | 18 | ## Affected Implementations 19 | 20 | | Language | Repository | 21 | | -------- | ----------------------------------------------------------------------------- | 22 | | Java | [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java) | 23 | | Python | [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python) | 24 | 25 | ## Definitions 26 | 27 | ### Conventions used in this document 28 | 29 | The key words 30 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 31 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 32 | in this document are to be interpreted as described in 33 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 34 | 35 | ## Summary 36 | 37 | The [Cryptographic Materials Cache (CMC)](../../framework/cryptographic-materials-cache.md) specification 38 | does not specify whether or not the Put Cache Entry operation 39 | returns the cache entry that it inserts. 40 | Some implementations do and others do not. 41 | This change specifies that the Put Cache Entry operation 42 | MUST NOT return the cache entry that it inserts. 43 | 44 | ## Out of Scope 45 | 46 | - Changing the shape of the caching CMM operations is out of scope. 47 | 48 | ## Motivation 49 | 50 | The [Cryptographic Materials Cache (CMC)](../../framework/cryptographic-materials-cache.md) specification 51 | does not specify whether or not the Put Cache Entry operation 52 | returns the cache entry that it inserts. 53 | Noting that the only user of the CMC is the 54 | [caching Cryptographic Materials Manager](../../framework/caching-cmm.md), 55 | we suppose that the operation does return the inserted entry 56 | and examine what the caching CMM might do with it. 57 | 58 | The caching CMM acquires cryptographic materials 59 | from an underlying CMM before placing them in the CMC 60 | via the Put Cache Entry operation. 61 | It also provides usage metadata to the operation 62 | so that the CMC can attach the metadata to the cache entry 63 | before storing the entry. 64 | But in the interest of separating concerns, 65 | the CMC does not include any other data in the cache entry, 66 | so the inserted cache entry ultimately contains only 67 | data that was originally provided by the caching CMM. 68 | It follows that the caching CMM has no reason 69 | to _read_ the inserted cache entry if the entry were returned. 70 | 71 | Furthermore, 72 | the caching CMM aims to provide only atomic operations, 73 | which necessitates that it reads and modifies the CMC state atomically. 74 | Suppose the caching CMM were to place materials in the CMC 75 | via the Put Cache Entry operation, 76 | receive the inserted entry via return value, 77 | and then modify the entry 78 | before returning the cryptographic materials to its caller. 79 | On the one hand, 80 | it is unsafe for the caching CMM to return the materials 81 | without writing the modified entry back to the CMC. 82 | On the other hand, 83 | it is not atomic if the caching does write the modified entry back to the CMC. 84 | It follows that the caching CMM has no safe way 85 | to _write_ to the inserted cache entry if the entry were returned, 86 | and so it has no good reason to. 87 | 88 | The caching CMM has reason 89 | neither to read nor write to a returned cache entry, 90 | so we conclude that the operation MUST NOT return the inserted cache entry. 91 | 92 | Indeed, 93 | the caching CMM ignores the operation's return value 94 | in every existing implementation 95 | where the operation returns the inserted cache entry 96 | (namely, the Java and Python implementations). 97 | This solidifies our view that the return value is unnecessary. 98 | 99 | ## Security Implications 100 | 101 | This change SHOULD NOT have any security implications. 102 | 103 | ## Operational Implications 104 | 105 | We MUST change the Java and Python implementations of Put Cache Entry 106 | to not return the inserted cache entry. 107 | 108 | ## Guide-level and Reference-level Explanation 109 | 110 | The Put Cache Entry operation MUST NOT return the inserted cache entry. 111 | -------------------------------------------------------------------------------- /changes/2022-06-19_seperate_material_providers/change.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Material Providers Library (MPL) 5 | 6 | ## Affected Features 7 | 8 | This serves as a reference of all features that this change affects. 9 | 10 | | Feature | 11 | | ----------------------------- | 12 | | [Framework](../../framework/) | 13 | 14 | ## Affected Specifications 15 | 16 | This serves as a reference of all specification documents that this change affects. 17 | 18 | | Specification | 19 | | ----------------------------------------------------------------------------- | 20 | | [Structures](../../framework/structures.md) | 21 | | [Keyring Interface](../../framework/keyring-interface.md) | 22 | | [AWS KMS Keyring](../../framework/kms-keyring.md) | 23 | | [Raw AES Keyring](../../framework/raw-aes-keyring.md) | 24 | | [Raw RSA Keyring](../../framework/raw-rsa-keyring.md) | 25 | | [Cryptographic Materials Manager Interface](../../framework/cmm-interface.md) | 26 | | [Default Cryptographic Materials Manager](../../framework/default-cmm.md) | 27 | 28 | ## Affected Implementations 29 | 30 | This serves as a reference for all implementations that this change affects. 31 | 32 | | Language | Version Introduced | Version Removed | Repository | 33 | | ---------- | ------------------ | --------------- | ------------------------------------------------------------------------------------- | 34 | | C | 0.1.0 | n/a | [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c) | 35 | | Javascript | 0.1.0 | n/a | [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript) | 36 | | Dafny | 0.1.0 | n/a | [aws-encryption-sdk-dafny](https://github.com/aws/aws-encryption-sdk-dafny) | 37 | | C# | 0.1.0 | n/a | [aws-encryption-sdk-dafny](https://github.com/aws/aws-encryption-sdk-dafny) | 38 | 39 | ## Definitions 40 | 41 | ### Conventions used in this document 42 | 43 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 44 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 45 | 46 | ## Summary 47 | 48 | We will rename the `framework` directory to `material_providers`, 49 | add a Readme.md, 50 | and update the algorithm-suites 51 | to be able to identify algorithm suites implemented by different libraries. 52 | 53 | ## Out of Scope 54 | 55 | - Algorithm suites for additional libraries. 56 | - Integrating this specification and the published library 57 | with ESDK-JS and ESDK-C. 58 | - Integrating the MPL with ESDK-Java and ESDK-Python 59 | 60 | ## Motivation 61 | 62 | We developed Cryptographic Materials Managers and Keyrings 63 | as a way for customers to easily configure their key distribution. 64 | Being able to reuse this logic in our other libraries 65 | will simplify our customers experience and use of our libraries. 66 | It will also simplify our development process 67 | and alow us to focus more on new formats and libraries. 68 | 69 | ## Drawbacks 70 | 71 | We will lose the freedom to add key distribution features 72 | that target specific libraries or storage platforms. 73 | However, [upon review](background.md) we concluded that 74 | we have not found any such features to date 75 | across the S3 Encryption Client (S3EC), DynamoDB Encryption Client (DDBEC), 76 | and the Encryption SDK (ESDK). 77 | 78 | ## Security Implications 79 | 80 | The main security implication of this change is the 81 | responsibility for the implementation details 82 | of a given Algorithm Suite move from being in the same library 83 | to being in a calling library. 84 | This is mitigated by having a tight coupling between 85 | the Material Providers Library and the callers (S3EC, DDBEC, ESDK). 86 | 87 | ## Operational Implications 88 | 89 | This will be a breaking change for the ESDK-Net. 90 | As we publish MPL integrating this with ESDK-JS and ESDK-C 91 | would also be breaking changes. 92 | But this affords us the opportunity 93 | to offer Keyring in both ESDK-Java and ESDK-Python. 94 | 95 | This change will affect custom keyrings/CMMs. 96 | This will have the largest impact on ESDK-JS and ESDK-C. 97 | The ESDK-Net has not existed long enough 98 | for significate custom keyring development. 99 | 100 | ## Guide-level Explanation 101 | 102 | CMMs and Keyings provide customers 103 | with a way to make security decisions for their plaintext, 104 | and configure their key distribution. 105 | After [reviewing the generality of this interface](background.md), 106 | we have come to the conclusion that all our libraries should 107 | use the same general interface to configure key distribution. 108 | 109 | From the specifications perspective we are mostly moving files. 110 | At a later date we may move the entire MPL directory 111 | into a separate github repo. 112 | 113 | However changes to the algorithm-suites will include 114 | adding an additional element of `library` 115 | to each suite to identify what `library` implements it. 116 | 117 | ## Reference-level Explanation 118 | 119 | ### Code Change 120 | 121 | Code changes required to make this change include: 122 | 123 | - Create a new set of `enums` for the ESDKs suites. 124 | - Change the current `AlgorithmSuiteId` into a union. 125 | - Update all references to `AlgorithmSuiteId` to disambiguate 126 | ESDK enums from other library enums. 127 | 128 | ### Examples 129 | 130 | All existing examples MUST be updated. 131 | -------------------------------------------------------------------------------- /changes/2023_7_12_update-keystore-structure/proposal.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Encryption context values that are authenticated but not stored with the encrypted message. 5 | 6 | ## Affected Features 7 | 8 | This serves as a reference of all features that this change affects. 9 | 10 | | Feature | 11 | | ----------------------------------------------- | 12 | | [Keystore](../../framework/branch-key-store.md) | 13 | | [Structures](../../framework/structures.md) | 14 | 15 | ## Affected Specifications 16 | 17 | This serves as a reference of all specification documents that this change affects. 18 | 19 | | Specification | 20 | | --------------------------------------------------------------------------------------- | 21 | | [Keystore](../../framework/branch-key-store.md) | 22 | | [Structures](../../framework/structures.md) | 23 | | [AWS KMS Hierarchical Keyring](../../framework/aws-kms/aws-kms-hierarchical-keyring.md) | 24 | 25 | ## Definitions 26 | 27 | ### Conventions used in this document 28 | 29 | The key words 30 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 31 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 32 | in this document are to be interpreted as described in 33 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 34 | 35 | ## Summary 36 | 37 | Inserting a record into the keystore table should correct by construction. 38 | The current design relied too heavily on GUID for correctness of the data in the table. 39 | A duplicate branch key id has the potential to create confusion 40 | about what data is encrypted under what AWS KMS key. 41 | By changing the data model we ensure that global unique guarantees 42 | are tied to the data model and reflected in the branch key structure. 43 | 44 | ## Out of Scope 45 | 46 | - Migration from the developer preview version 47 | - Local policy evaluation for use of branch keys 48 | 49 | ## Motivation 50 | 51 | Customers were very interested in defining their own branch key ids. 52 | As they implemented their own branch key creation process 53 | this lead them to ask 54 | “how can I ensure that there does not already exist a branch key for this id?” 55 | This illustrated that the design relied too heavily on GUID for correctness. 56 | 57 | The fact that they were willing to invest in their own code 58 | to manage branch key id creation illustrated that this is an important feature. 59 | It is likely that they would have tried to use private function 60 | to try and maintain forward compatibility with upstream changes. 61 | 62 | The goal then is to simplify the structure and offer the feature. 63 | 64 | ## Operational Implications 65 | 66 | This change will invalidate existing keystore tables. 67 | Given that the current code is in developer preview 68 | this is an acceptable risk. 69 | The library is documented as not ready for production workloads. 70 | 71 | ## Reference-level Explanation 72 | 73 | ### Remove the Global Secondary Index 74 | 75 | on [CreateKeyStore](../../framework/branch-key-store.md#createkey). 76 | 77 | This is no longer used and does not need to exist. 78 | 79 | ### New input branch-key-id and encryption context 80 | 81 | on [CreateKey](../../framework/branch-key-store.md#createkey) 82 | 83 | The input needs to be able to take two new optional inputs 84 | 85 | - branch key id 86 | - encryption context 87 | 88 | It needs to be able to add the new encryption context 89 | to the branch key item. 90 | As well as require that a custom branch key id 91 | also requires additional encryption context for validation. 92 | 93 | ### Update the creation logic to insert 3 records 94 | 95 | on [CreateKey](../../framework/branch-key-store.md#createkey) 96 | 97 | The active and the version items as well as the beacon item 98 | need to be inserted. 99 | 100 | ### New section Wrapped Branch Key Creation 101 | 102 | Add a new section to specify how a key is created. 103 | This can be used both on branch key creation 104 | but also on versioning. 105 | Since in that case a new version key is also created. 106 | 107 | ### Add ConditionExpression to writing to DDB 108 | 109 | on both [Writing Branch Key and Beacon Key to Keystore](../../framework/branch-key-store.md#writing-branch-key-and-beacon-key-to-keystore) 110 | and [VersionKey](../../framework/branch-key-store.md#versionkey). 111 | 112 | When writing a new key, all 3 records MUST NOT exist. 113 | When versioning a key, the active record MUST already exist, 114 | and the new version MUST NOT exist. 115 | 116 | ### Update the fixed constants and prefixes for DDB attributes 117 | 118 | Updating fixed constants to`beacon:ACTIVE` and `branch:ACTIVE` 119 | it is very clear what they are. 120 | This namespaces other values that may need to be associated with the key. 121 | 122 | By updating the version prefix from `version:` to `branch:version:` 123 | this ties the record more closely to the branch keys. 124 | 125 | ### Add a new prefix for encryption context for DDB attributes 126 | 127 | `aws-crypto-ec:` for any custom encryption context added to the branch key on creation. 128 | 129 | ### Add example records 130 | 131 | Examples are helpful to visualize what the data should look like. 132 | 133 | ### Update the Hierarchical Keyring to use branch material 134 | 135 | in [AWS KMS Hierarchical Keyring](../../framework/aws-kms/aws-kms-hierarchical-keyring.md#query-branch-keystore-onencrypt) 136 | expects the keystore to return bytes. 137 | However the keystore specification returns branch key materials. 138 | 139 | ### New property encryption context 140 | 141 | on [Branch Key Materials](../../framework/structures.md#branch-key-materials). 142 | Given that the materials have not authenticated these values 143 | they should be stored on the materials. 144 | 145 | ### Add information about optional Beacon Key. 146 | 147 | The beacon key is optional 148 | because it can then be removed 149 | after being used to derive HMAC Keys. 150 | Adding clarification to make this clear. 151 | -------------------------------------------------------------------------------- /changes/2024-6-17_key-store-persistance/proposed.smithy: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | structure KeyStoreConfig { 5 | 6 | @required 7 | kmsConfiguration: KMSConfiguration, 8 | @required 9 | logicalKeyStoreName: String, 10 | 11 | id: String, 12 | 13 | // These properties are about storage 14 | storage: Storage 15 | ddbTableName: TableName, 16 | ddbClient: DdbClientReference, 17 | 18 | // These properties are about authentication/authorization 19 | auth: Auth, 20 | grantTokens: GrantTokenList, 21 | kmsClient: KmsClientReference, 22 | 23 | } 24 | 25 | union Storage { 26 | ddb: DynamoDBTable 27 | custom: EncryptedKeyStore 28 | } 29 | 30 | structure DynamoDBTable { 31 | @required 32 | ddbTableName: TableName, 33 | ddbClient: DdbClientReference, 34 | } 35 | 36 | union Auth { 37 | kms: AwsKms, 38 | } 39 | 40 | structure AwsKms { 41 | grantTokens: GrantTokenList, 42 | kmsClient: KmsClientReference, 43 | } 44 | 45 | enum BranchKeyType { 46 | ACTIVE_BRANCH_KEY 47 | BRANCH_KEY_VERSION 48 | } 49 | 50 | enum BranchKeyKind { 51 | HIERARCHICAL_SYMMETRIC 52 | } 53 | 54 | structure EncryptedBranchKey { 55 | @required 56 | Identifier: Utf8Bytes, 57 | 58 | @required 59 | Type: BranchKeyType, 60 | 61 | @required 62 | Kind: BranchKeyKind, 63 | 64 | @required 65 | Version: Utf8Bytes, 66 | 67 | @required 68 | CreateTime: Utf8Bytes, 69 | 70 | @required 71 | KmsArn: Utf8Bytes, 72 | 73 | @required 74 | EncryptionContext: EncryptionContext, 75 | 76 | @required 77 | CiphertextBlob: blob, 78 | } 79 | 80 | structure EncryptedBeaconKey { 81 | @required 82 | Identifier: Utf8Bytes, 83 | 84 | @required 85 | CreateTime: Utf8Bytes, 86 | 87 | @required 88 | KmsArn: Utf8Bytes, 89 | 90 | @required 91 | EncryptionContext: EncryptionContext, 92 | 93 | @required 94 | CiphertextBlob: blob, 95 | } 96 | 97 | union EncryptedBranchItem { 98 | BranchKey: EncryptedBranchKey 99 | } 100 | 101 | union EncryptedBeaconItem { 102 | BeaconKey: EncryptedBeaconKey 103 | } 104 | 105 | @extendable 106 | resource EncryptedKeyStore { 107 | operations: [ 108 | GetEncryptedActiveBranchKey, 109 | GetEncryptedBranchKeyVersion, 110 | GetEncryptedBeaconKey, 111 | ] 112 | } 113 | 114 | @reference(resource: EncryptedKeyStore) 115 | structure EncryptedKeyStoreReference {} 116 | 117 | operation GetEncryptedActiveBranchKey { 118 | input: GetEncryptedActiveBranchKeyInput, 119 | output: GetEncryptedActiveBranchKeyOutput, 120 | } 121 | operation GetEncryptedBranchKeyVersion { 122 | input: GetEncryptedBranchKeyVersionInput, 123 | output: GetEncryptedBranchKeyVersionOutput, 124 | } 125 | operation GetEncryptedBeaconKey { 126 | input: GetEncryptedBeaconKeyInput, 127 | output: GetEncryptedBeaconKeyOutput, 128 | } 129 | 130 | structure GetEncryptedActiveBranchKeyInput{ 131 | @required 132 | Identifier: Utf8Bytes, 133 | } 134 | structure GetEncryptedActiveBranchKeyOutput{ 135 | Item: EncryptedBranchItem, 136 | } 137 | structure GetEncryptedBranchKeyVersionInput{ 138 | @required 139 | Identifier: Utf8Bytes, 140 | @required 141 | Version: Utf8Bytes, 142 | } 143 | structure GetEncryptedBranchKeyVersionOutput{ 144 | Item: EncryptedBranchItem, 145 | } 146 | structure GetEncryptedBeaconKeyInput{ 147 | @required 148 | Identifier: Utf8Bytes, 149 | } 150 | structure GetEncryptedBeaconKeyOutput{ 151 | Item: EncryptedBeaconItem, 152 | } -------------------------------------------------------------------------------- /changes/2025-01-16_key-store-mitigate-update-race/background.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Mitigate Update Race in Branch Key Store 5 | 6 | # Definitions 7 | 8 | ## MPL 9 | 10 | Material Providers Library 11 | 12 | ## Conventions used in this document 13 | 14 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", 15 | "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be 16 | interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 17 | 18 | # Background 19 | 20 | The [branch key store](../../framework/branch-key-store.md) needs to persist branch key versions. 21 | DynamoDB was selected as an easy-to-use option, 22 | with an interface later introduced to allow customers 23 | to implement other storage options. 24 | 25 | The behavior of the `WriteNewEncryptedBranchKeyVersion` operation 26 | leaves open a possibility for a normally benign overwrite 27 | of the cipher-text of a Branch Key, 28 | should two or more agents a Version a Branch Key simultaneously. 29 | 30 | This change mitigates this. 31 | 32 | ## Detailed Explanation 33 | 34 | The Key Store's `VersionKey` operation does NOT, 35 | at this time, 36 | validate that the ACTIVE item has NOT been modified 37 | since it read the item. 38 | 39 | This allows the Key Store's `VersionKey` operation 40 | to race itself. 41 | 42 | `VersionKey`'s self-race is benign; 43 | the only consequence is an additional 44 | but unneeded versions of the Branch Key. 45 | 46 | However, 47 | Crypto Tools or it's customers may write logic 48 | that modify Branch Key items in other ways. 49 | 50 | Such modifications, 51 | if overwritten due to a race, 52 | may break customers or methods Crypto Tools 53 | introduces to modify Branch Keys. 54 | 55 | Thus, 56 | Crypto Tools should refactor the Storage interface 57 | to mitigate the unintended overwrite. 58 | 59 | ## Optimistic Lock 60 | 61 | We will mitigate this via an Optimistic Lock on the cipher-text. 62 | 63 | All writes to ACTIVE, 64 | except those by `CreateKey`, 65 | would include a condition expression of 66 | `attribute_exists(branch-key-id) AND enc = `, 67 | as [expressed in DynamoDB Syntax](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html). 68 | 69 | `enc` gives an assertion on the state of: 70 | 71 | - any custom encryption context 72 | - the creation date 73 | - the hierarchy-version 74 | - the Logical Key Store Name 75 | 76 | `enc` contains the Auth Tag from 77 | the AES-GCM operation executed by KMS. 78 | 79 | Thus, by asserting `enc` has not changed, 80 | the Key Store asserts that nothing has changed! 81 | 82 | Since this _Optimistic Lock_ is only 83 | applied AFTER the `enc` value has 84 | been validated by KMS 85 | during the Version routine, 86 | the Key Store KNOWS `enc` is valid. 87 | 88 | If `enc` has been changed, 89 | the write will fail with an error detailing the condition check failure. 90 | 91 | # Changes 92 | 93 | The change is to use an Optimistic Lock 94 | on the old cipher-text value. 95 | 96 | This refactors: 97 | 98 | - The [Branch Key Store's VersionKey](../../framework/branch-key-store.md#versionkey) 99 | - The [Key Storage's WriteNewEncryptedBranchKeyVersion](../../framework/key-store/key-storage.md#writenewencryptedbranchkeyversion) 100 | - The [Dynamodb Key Storage's WriteNewEncryptedBranchKeyVersion](../../framework/key-store/dynamodb-key-storage.md#writenewencryptedbranchkeyversion) 101 | 102 | These refactors are to use the old Active's cipher-text 103 | as the optimistic lock. 104 | -------------------------------------------------------------------------------- /ci/prettify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case "${1}" in 4 | write) 5 | npx prettier --config .prettierrc.toml --write -- '**/*.md' !./history/**/* 6 | ;; 7 | check) 8 | npx prettier --config .prettierrc.toml --check -- '**/*.md' 9 | ;; 10 | *) 11 | echo "mode required!" 12 | echo "${0} [write/check]" 13 | exit 1 14 | ;; 15 | esac 16 | -------------------------------------------------------------------------------- /client-apis/client.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Client 5 | 6 | ## Version 7 | 8 | 0.1.0 9 | 10 | ## Implementations 11 | 12 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 13 | | ---------- | -------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | 14 | | C | 0.1.0 | 0.1.0 | [session.c](https://github.com/aws/aws-encryption-sdk-c/blob/master/source/session.c) | 15 | | NodeJS | 0.1.0 | 0.1.0 | [index.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/client-node/src/index.ts) | 16 | | Browser JS | 0.1.0 | 0.1.0 | [index.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/client-browser/src/index.ts) | 17 | | Python | 0.1.0 | 0.1.0 | [\_\_init\_\_.py](https://github.com/aws/aws-encryption-sdk-python/blob/master/src/aws_encryption_sdk/__init__.py) | 18 | | Java | 0.1.0 | 0.1.0 | [AwsCrypto.java](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java) | 19 | 20 | ## Overview 21 | 22 | This document describes the client experience for the AWS Encryption SDK. 23 | 24 | The top level client supports configuration settings 25 | that need to be coordinated between encrypt and decrypt. 26 | Coordinating static settings between encrypt and decrypt across hosts is complicated. 27 | It is important that all messages that could be sent to a host can be decrypted by that host. 28 | A top level client makes such settings [hard to misuse](https://github.com/awslabs/aws-encryption-sdk-specification/blob/master/tenets.md#hard-to-misuse) 29 | because anything a client encrypts can be decrypted by the same client. 30 | 31 | ## Initialization 32 | 33 | On client initialization, 34 | the caller MUST have the option to provide a: 35 | 36 | - [commitment policy](#commitment-policy) 37 | - [maximum number of encrypted data keys](#maximum-number-of-encrypted-data-keys) 38 | 39 | If no [commitment policy](#commitment-policy) is provided the default MUST be [REQUIRE_ENCRYPT_REQUIRE_DECRYPT](../framework/algorithm-suites.md#require_encrypt_require_decrypt). 40 | If no [maximum number of encrypted data keys](#maximum-number-of-encrypted-data-keys) is provided 41 | the default MUST result in no limit on the number of encrypted data keys (aside from the limit imposed by the [message format](../format/message-header.md)). 42 | 43 | Once a [commitment policy](#commitment-policy) has been set it SHOULD be immutable. 44 | 45 | ### Commitment Policy 46 | 47 | Some algorithm suites provide a commitment 48 | that one and only one data key 49 | can be used to decrypt the plaintext. 50 | Commitment policies control which algorithm suites are enabled 51 | for [encrypt](encrypt.md) and [decrypt](decrypt.md). 52 | As well as which algorithm suite is the default. 53 | 54 | The AWS Encryption SDK MUST provide the following commitment policies: 55 | 56 | - FORBID_ENCRYPT_ALLOW_DECRYPT 57 | - REQUIRE_ENCRYPT_ALLOW_DECRYPT 58 | - REQUIRE_ENCRYPT_REQUIRE_DECRYPT 59 | 60 | ### Maximum Number Of Encrypted Data Keys 61 | 62 | A AWS Encryption SDK message can contain multiple encrypted data keys. 63 | This is the maximum number of encrypted data keys that the client will attempt to unwrap. 64 | Callers MUST have a way to disable this limit. 65 | 66 | #### FORBID_ENCRYPT_ALLOW_DECRYPT 67 | 68 | When the commitment policy `FORBID_ENCRYPT_ALLOW_DECRYPT` is configured: 69 | 70 | - `03 78` MUST be the default algorithm suite 71 | - [encrypt](encrypt.md) MUST only support algorithm suites that have a [Key Commitment](../framework/algorithm-suites.md#algorithm-suites-encryption-key-derivation-settings) value of False 72 | - [decrypt](decrypt.md) MUST support all algorithm suites 73 | 74 | #### REQUIRE_ENCRYPT_ALLOW_DECRYPT 75 | 76 | When the commitment policy `REQUIRE_ENCRYPT_ALLOW_DECRYPT` is configured: 77 | 78 | - `05 78` MUST be the default algorithm suite 79 | - [encrypt](encrypt.md) MUST only support algorithm suites that have a [Key Commitment](../framework/algorithm-suites.md#algorithm-suites-encryption-key-derivation-settings) value of True 80 | - [decrypt](decrypt.md) MUST support all algorithm suites 81 | 82 | #### REQUIRE_ENCRYPT_REQUIRE_DECRYPT 83 | 84 | When the commitment policy `REQUIRE_ENCRYPT_REQUIRE_DECRYPT` is configured: 85 | 86 | - `05 78` MUST be the default algorithm suite 87 | - [encrypt](encrypt.md) MUST only support algorithm suites that have a [Key Commitment](../framework/algorithm-suites.md#algorithm-suites-encryption-key-derivation-settings) value of True 88 | - [decrypt](decrypt.md) MUST only support algorithm suites that have a [Key Commitment](../framework/algorithm-suites.md#algorithm-suites-encryption-key-derivation-settings) value of True 89 | 90 | ## Operation 91 | 92 | ### Encrypt 93 | 94 | The AWS Encryption SDK Client MUST provide an [encrypt](./encrypt.md#input) function 95 | that adheres to [encrypt](./encrypt.md). 96 | 97 | ### Decrypt 98 | 99 | The AWS Encryption SDK Client MUST provide an [decrypt](./decrypt.md#input) function 100 | that adheres to [decrypt](./decrypt.md). 101 | -------------------------------------------------------------------------------- /client-apis/streaming.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Streaming 5 | 6 | ## Version 7 | 8 | 0.1.0 9 | 10 | ### Changelog 11 | 12 | - 0.1.0 13 | 14 | - [Clarify Streaming Encrypt and Decrypt](../changes/2020-07-06_clarify-streaming-encrypt-decrypt/change.md) 15 | 16 | ## Overview 17 | 18 | The AWS Encryption SDK MAY provide APIs that enable streamed [encryption](encrypt.md) 19 | and [decryption](decrypt.md). 20 | Streaming is a framework for making bytes available to be processed 21 | by an operation sequentially and over time, 22 | and for outputting the result of that processing 23 | sequentially and over time. 24 | 25 | If an implementation requires holding the entire input in memory in order to perform the operation, 26 | that implementation SHOULD NOT provide an API that allows the caller to stream the operation. 27 | APIs that support streaming of the encrypt or decrypt operation SHOULD allow customers 28 | to be able to process arbitrarily large inputs with a finite amount of working memory. 29 | 30 | ## Definitions 31 | 32 | ### Conventions used in this document 33 | 34 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 35 | in this document are to be interpreted as described in [RFC2119](https://tools.ietf.org/html/rfc2119). 36 | 37 | ### Consumable Bytes 38 | 39 | In the scope of an operation, bytes are considered consumable if: 40 | 41 | - The operation has not yet processed those bytes. 42 | - The operation has access to those bytes. 43 | - Those bytes are intended to be processed. 44 | This intention is expressed through the specific streaming interface. 45 | 46 | For example, in a framework where a customer is sending input bytes to an operation 47 | and that operation must write the output bytes to some sink, 48 | the input bytes received from the customer are considered consumable. 49 | Here the customer is expressing intent to process their supplied bytes. 50 | 51 | For a framework where a customer is requesting output bytes from an operation 52 | and that operation must read from some source in order to produce bytes, 53 | this is slightly more complicated. 54 | Bytes are considered consumable if: 55 | 56 | - Those bytes have not yet been processed. 57 | - Those bytes are able to be read by the operation from the source. 58 | - Those bytes are required to be processed in order for the operation 59 | to release the output requested by the customer. 60 | Here the customer expresses intent for the operation to process 61 | whatever the operation needs to consume to produce its complete output 62 | 63 | ### Release 64 | 65 | An operation releases bytes when the operation intends those bytes to be considered output. 66 | 67 | For example, in a framework where a customer is sending input bytes to an operation 68 | and that operation must write the output bytes to some sink, 69 | bytes are considered released once the operation writes those bytes into the sink. 70 | 71 | For a framework where a customer is requesting output bytes from an operation 72 | and that operation must read from some source in order to produce bytes, 73 | bytes are considered released once those bytes are available to be read by the customer. 74 | 75 | If bytes are processed by an operation, that does not imply that the operation is allowed to 76 | release any result of that processing. 77 | The decrypt and encrypt operations specify when output bytes MUST NOT be released 78 | and when they SHOULD be released. 79 | 80 | ## Inputs 81 | 82 | In order to support streaming, the operation MUST accept some input within a streaming framework. 83 | 84 | This means that: 85 | 86 | - There MUST be a mechanism for input bytes to become consumable. 87 | - There MUST be a mechanism to indicate that there are no more input bytes. 88 | 89 | These mechanisms are used to allow the operation to process input bytes in parts, over time. 90 | 91 | The bytes that represent the entire input to the operation are the bytes that the customer intended 92 | to be processed. 93 | 94 | ## Outputs 95 | 96 | In order to support streaming, the operation MUST produce some output within a streaming framework. 97 | 98 | This means that: 99 | 100 | - There MUST be a mechanism for output bytes to be released. 101 | - There MUST be a mechanism to indicate that the entire output has been released. 102 | 103 | These mechanisms are used to allow the operation to produce output bytes in parts, over time. 104 | 105 | The bytes that represent the entire output to the operation are the bytes that were released 106 | up until an end was indicated. 107 | 108 | Operations MUST NOT indicate completion or success until an end to the output has been indicated. 109 | 110 | ## Behavior 111 | 112 | By using the mechanisms for [inputs](#inputs) and [outputs](#outputs), 113 | some actor expresses intent through a streaming interface 114 | for bytes to be made consumable to the operation 115 | and for bytes to be released by the operation. 116 | 117 | The behavior of the operation specifies how the operation processes consumable bytes, 118 | and specifies when processed bytes MUST NOT and SHOULD be released. 119 | -------------------------------------------------------------------------------- /data-format/message-body-aad.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Message Body AAD 5 | 6 | ## Version 7 | 8 | See [Message Version](message.md#version). 9 | 10 | ## Implementations 11 | 12 | - [C](https://github.com/aws/aws-encryption-sdk-c/blob/master/source/cipher.c) 13 | - [JavaScript](https://github.com/awslabs/aws-encryption-sdk-javascript/blob/master/modules/serialize/src/aad_factory.ts) 14 | - [Python](https://github.com/aws/aws-encryption-sdk-python/blob/master/src/aws_encryption_sdk/internal/formatting/encryption_context.py) 15 | - [Java](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/internal/Utils.java) 16 | 17 | ## Overview 18 | 19 | The message body AAD is the serialization of the AAD to be used as input to encryption of the message body. 20 | 21 | ## Structure 22 | 23 | The following describes the fields that form the message body AAD. 24 | The bytes are appended in the order shown. 25 | 26 | | Field | Length (bytes) | Interpreted as | 27 | | ---------------- | -------------- | -------------- | 28 | | Message ID | 16 | Bytes | 29 | | Body AAD Content | Variable. | UTF-8 Bytes | 30 | | Sequence Number | 4 | Uint32 | 31 | | Content Length | 8 | Uint64 | 32 | 33 | ### Message ID 34 | 35 | An identifier for the [message](message.md) this message body AAD is associated with. 36 | 37 | ### Body AAD Content 38 | 39 | An identifier for the content type of the data this message body AAD is associated with. 40 | 41 | This value depends on the [content type](message-header.md#content-type) of the [message](message.md): 42 | 43 | - [Non-framed data](message-body.md#non-framed-data) MUST use the value `AWSKMSEncryptionClient Single Block`. 44 | - The [regular frames](message-body.md#regular-frame) in [framed data](message-body.md#framed-data) MUST use the value `AWSKMSEncryptionClient Frame`. 45 | - The [final frame](message-body.md#final-frame) in [framed data](message-body.md#framed-data) MUST use the value `AWSKMSEncryptionClient Final Frame`. 46 | 47 | ### Sequence Number 48 | 49 | The sequence number of the data this message body AAD belongs to. 50 | For [framed data](message-body.md#framed-data), the value of this field MUST be the [frame sequence number](message-body.md#sequence-number). 51 | For [non-framed data](message-body.md#non-framed-data), the value of this field MUST be `1`. 52 | 53 | ### Content Length 54 | 55 | The length, in bytes, of the plaintext data being encrypted that this message body AAD is associated with. 56 | 57 | More specifically, depending on the [content type](message-header.md#content-type) of the [message](message.md): 58 | 59 | - For [non-framed data](message-body.md#non-framed-data), this value MUST equal the length, in bytes, 60 | of the plaintext data provided to the algorithm for encryption. 61 | - For [framed data](message-body.md#framed-data), this value MUST equal the length, in bytes, 62 | of the plaintext being encrypted in this frame. 63 | - For [regular frames](message-body.md#regular-frame), this value MUST equal the value of 64 | the [frame length](message-header.md#frame-length) field in the message header. 65 | - For the [final frame](message-body.md#final-frame), this value MUST be greater than or equal to 66 | 0 and less than or equal to the value of the [frame length](message-header.md#frame-length) 67 | field in the message header. 68 | -------------------------------------------------------------------------------- /data-format/message-footer.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Footer Structure 5 | 6 | ## Version 7 | 8 | See [Message Version](message.md#version). 9 | 10 | ## Implementations 11 | 12 | - [C](https://github.com/awslabs/aws-encryption-sdk-c/blob/master/source/session_encrypt.c) 13 | - [JavaScript](https://github.com/awslabs/aws-encryption-sdk-javascript/blob/master/modules/serialize/src/signature_info.ts) 14 | - [Python](https://github.com/aws/aws-encryption-sdk-python/blob/master/src/aws_encryption_sdk/internal/structures.py) 15 | - [Java](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/model/CiphertextFooters.java) 16 | 17 | ## Overview 18 | 19 | The footer is a component of the [message](message.md). 20 | When an [algorithm suite](../framework/algorithm-suites.md) includes a [signature algorithm](../framework/algorithm-suites.md#signature-algorithm), 21 | the [message](message.md) MUST contain a footer. 22 | 23 | ## Definitions 24 | 25 | ### Conventions used in this document 26 | 27 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 28 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 29 | 30 | ## Structure 31 | 32 | The following describes the fields that form the footer. 33 | The bytes are appended in the order shown. 34 | 35 | | Field | Length (bytes) | Interpreted as | 36 | | ---------------- | -------------- | -------------- | 37 | | Signature Length | 2 | Uint16 | 38 | | Signature | Variable. | Bytes | 39 | 40 | ### Signature Length 41 | 42 | The length of the signature. 43 | 44 | ### Signature 45 | 46 | The [signature](../framework/algorithm-suites.md#signature-algorithm) used to authenticate the message. 47 | This signature MUST be calculated over both the [message header](message-header.md) and the [message body](message-body.md), 48 | in the order of serialization. 49 | The [algorithm suite](../framework/algorithm-suites.md) specified by the [Algorithm Suite ID](../framework/algorithm-suites.md#algorithm-suite-id) field 50 | [determines how the value of this field is calculated](../client-apis/encrypt.md), 51 | and uses this value to [authenticate the contents of the header and body during decryption](../client-apis/decrypt.md). 52 | 53 | ## Example Usage 54 | 55 | The following section contains examples of the footer. 56 | 57 | ### Example Pseudo-ASN.1 Structure 58 | 59 | ``` 60 | DEFINITIONS ::= BEGIN 61 | Footer SEQUENCE (SIZE(2)) { 62 | SignatureLength UINT16, 63 | Signature OCTET STRING (SIZE(SignatureLength)), 64 | } 65 | ``` 66 | 67 | ### Example Bytes 68 | 69 | ``` 70 | 0067 Signature Length (103) 71 | 30650230 7229DDF5 B86A5B64 54E4D627 Signature 72 | CBE194F1 1CC0F8CF D27B7F8B F50658C0 73 | BE84B355 3CED1721 A0BE2A1B 8E3F449E 74 | 1BEB8281 023100B2 0CB323EF 58A4ACE3 75 | 1559963B 889F72C3 B15D1700 5FB26E61 76 | 331F3614 BC407CEE B86A66FA CBF74D9E 77 | 34CB7E4B 363A38 78 | ``` 79 | -------------------------------------------------------------------------------- /data-format/message.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Message 5 | 6 | ## Version 7 | 8 | 0.2.0 9 | 10 | Note: This is the version of the message specification, 11 | not the message format. 12 | 13 | ## Overview 14 | 15 | A message is a formatted structure that contains encrypted data and associated metadata. 16 | 17 | ## Structure 18 | 19 | A message is a sequence of bytes that is the serialization of the following, in order: 20 | 21 | - [Message Header](message-header.md) 22 | - [Message Body](message-body.md) 23 | 24 | If the [message header](message-header.md) contains an [algorithm suite](../framework/algorithm-suites.md) in the 25 | [algorithm suite ID](message-header.md#algorithm-suite-id) field that contains a 26 | [signature algorithm](../framework/algorithm-suites.md#signature-algorithm), the message MUST also contain a 27 | [message footer](message-footer.md), serialized after the [message body](message-body.md). 28 | -------------------------------------------------------------------------------- /examples/examples.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Required Examples 5 | 6 | ## Version 7 | 8 | 0.2.0 9 | 10 | ### Changelog 11 | 12 | - 0.2.0 13 | 14 | - Add [Example Templates](#example-templates) section 15 | 16 | - 0.1.0 17 | 18 | - [Require examples](../changes/2020-06-16_required-examples/change.md) 19 | 20 | ## Implementations 21 | 22 | - [Python (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/) 23 | - [Java (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/) 24 | 25 | ## Overview 26 | 27 | Every implementation MUST include an example 28 | for each use-case described in [example templates](./templates). 29 | 30 | ## Definitions 31 | 32 | ### Conventions used in this document 33 | 34 | The key words 35 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 36 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 37 | in this document are to be interpreted as described in 38 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 39 | 40 | ## Requirements 41 | 42 | - Every example MUST be tested 43 | as part of the continuous integration testing. 44 | - Every example MUST be independent and complete. 45 | - Every example SHOULD follow a consistent layout and framing. 46 | 47 | - ex: Consistent function name and input parameters across examples. 48 | 49 | - Every example MUST only contain logic that is reasonable for production use. 50 | - If an example MUST contain logic that is not reasonable for production use, 51 | it MUST include clear comments identifying that logic as such 52 | and instructing the reader what they SHOULD do instead. 53 | 54 | - ex: Raw keyring examples generate wrapping keys as part of the example. 55 | These examples MUST contain guidance that 56 | in production those keys SHOULD be managed by an HSM. 57 | 58 | ### Example Templates 59 | 60 | Each example is defined by a [template](./templates). 61 | Templates MUST include sufficient code to clearly demonstrate 62 | how to implement an example. 63 | This code MAY be in any language. 64 | 65 | Each template MUST contain the following sections: 66 | 67 | 1. Header : 68 | This is a detailed description 69 | that independently describes the purpose of the example 70 | and what it describes. 71 | It includes any links to supporting documentation. 72 | 73 | - Implementations MUST include this text verbatim 74 | at the top of the file, 75 | adjusted appropriately for language comment syntax. 76 | 77 | 1. Summary : 78 | One-sentence summary of the header. 79 | 80 | - Implementations MUST include this text verbatim 81 | in the documentation for the example entry point 82 | function/method/etc, 83 | adjusted appropriately for language comment syntax. 84 | 85 | 1. Inputs : 86 | List of inputs that the example entry point MUST accept, 87 | with an accompanying description. 88 | 89 | - Implementations MUST provide all of these inputs in CI 90 | as part of their testing framework. 91 | - Implementations MUST name their inputs to match the naming of 92 | the input in the template. 93 | - Implementations MUST use the description text verbatim, 94 | adjusted appropriately for language comment syntax. 95 | 96 | 1. Steps : 97 | List of steps that define the example. 98 | 99 | - Implementations MUST include every step. 100 | - Implementations MUST include any comments verbatim, 101 | adjusted appropriately for language comment syntax. 102 | - Implementations MAY alter the order of steps 103 | if another order is more appropriate for that language. 104 | -------------------------------------------------------------------------------- /examples/templates/configuration/raw-keyrings/raw-aes-keyring.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Raw AES keyring example 5 | 6 | Implementations of this example MUST follow the rules defined in 7 | [Example Templates](../../../examples.md#example-templates). 8 | 9 | ## Implementations 10 | 11 | - [Python (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/src/keyring/raw_aes/raw_aes.py) 12 | - [Python Master Key Provider (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/src/master_key_provider/raw_aes/raw_aes.py) 13 | - [Java (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java) 14 | - [Java Master Key Provider (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/java/com/amazonaws/crypto/examples/masterkeyprovider/rawaes/RawAes.java) 15 | 16 | ## Definitions 17 | 18 | ### Conventions used in this document 19 | 20 | The key words 21 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 22 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 23 | in this document are to be interpreted as described in 24 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 25 | 26 | ## Header 27 | 28 | ```python 29 | # This examples shows how to configure and use a raw AES keyring. 30 | # 31 | # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring 32 | # 33 | # In this example, we use the one-step encrypt and decrypt APIs. 34 | ``` 35 | 36 | ## Summary 37 | 38 | ```python 39 | # Demonstrate an encrypt/decrypt cycle using a raw AES keyring. 40 | ``` 41 | 42 | ## Inputs 43 | 44 | - **source plaintext** : 45 | Plaintext to encrypt 46 | 47 | ## Steps 48 | 49 | 1. Define encryption context. 50 | 51 | ```python 52 | # Prepare your encryption context. 53 | # Remember that your encryption context is NOT SECRET. 54 | # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context 55 | encryption_context = { 56 | "encryption": "context", 57 | "is not": "secret", 58 | "but adds": "useful metadata", 59 | "that can help you": "be confident that", 60 | "the data you are handling": "is what you think it is", 61 | } 62 | ``` 63 | 64 | 1. Generate the wrapping key. 65 | 66 | ```python 67 | # Generate a 256-bit (32 byte) AES key to use with your keyring. 68 | # 69 | # In practice, you should get this key from a secure key management system such as an HSM. 70 | key = os.urandom(32) 71 | ``` 72 | 73 | 1. Create keyring. 74 | 75 | ```python 76 | # Create the keyring that determines how your data keys are protected. 77 | keyring = RawAESKeyring( 78 | # The key namespace and key name are defined by you 79 | # and are used by the raw AES keyring 80 | # to determine whether it should attempt to decrypt 81 | # an encrypted data key. 82 | # 83 | # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring 84 | key_namespace="some managed raw keys", 85 | key_name="my AES wrapping key", 86 | wrapping_key=key, 87 | ) 88 | ``` 89 | 90 | 1. Encrypt plaintext data. 91 | 92 | ```python 93 | # Encrypt your plaintext data. 94 | ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( 95 | source=source_plaintext, encryption_context=encryption_context, keyring=keyring 96 | ) 97 | ``` 98 | 99 | 1. Compare ciphertext to plaintext. 100 | 101 | ```python 102 | # Demonstrate that the ciphertext and plaintext are different. 103 | assert ciphertext != source_plaintext 104 | ``` 105 | 106 | 1. Decrypt encrypted data. 107 | 108 | ```python 109 | # Decrypt your encrypted data using the same keyring you used on encrypt. 110 | # 111 | # You do not need to specify the encryption context on decrypt 112 | # because the header of the encrypted message includes the encryption context. 113 | decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, keyring=keyring) 114 | ``` 115 | 116 | 1. Compare the decrypted plaintext and original plaintext. 117 | 118 | ```python 119 | # Demonstrate that the decrypted plaintext is identical to the original plaintext. 120 | assert decrypted == source_plaintext 121 | ``` 122 | 123 | 1. Verify the encryption context. 124 | 125 | ```python 126 | # Verify that the encryption context used in the decrypt operation includes 127 | # the encryption context that you specified when encrypting. 128 | # The AWS Encryption SDK can add pairs, so don't require an exact match. 129 | # 130 | # In production, always use a meaningful encryption context. 131 | assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items()) 132 | ``` 133 | -------------------------------------------------------------------------------- /examples/templates/configuration/raw-keyrings/raw-rsa-keyring.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Basic raw RSA keyring example 5 | 6 | Implementations of this example MUST follow the rules defined in 7 | [Example Templates](../../../examples.md#example-templates). 8 | 9 | ## Implementations 10 | 11 | - [Python (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/src/keyring/raw_rsa/keypair.py) 12 | - [Java (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java) 13 | - [Java Master Key Provider (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/java/com/amazonaws/crypto/examples/masterkeyprovider/rawrsa/RawRsa.java) 14 | 15 | ## Definitions 16 | 17 | ### Conventions used in this document 18 | 19 | The key words 20 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 21 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 22 | in this document are to be interpreted as described in 23 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 24 | 25 | ## Header 26 | 27 | ```python 28 | # This example shows how to configure and use a raw RSA keyring using a pre-loaded RSA keypair. 29 | # 30 | # If your RSA key is in PEM or DER format, 31 | # see the ``keyring/raw_rsa/private_key_only_from_pem`` example. 32 | # 33 | # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-rsa-keyring 34 | # 35 | # In this example, we use the one-step encrypt and decrypt APIs. 36 | ``` 37 | 38 | ## Summary 39 | 40 | ```python 41 | # Demonstrate an encrypt/decrypt cycle using a raw RSA keyring. 42 | ``` 43 | 44 | ## Inputs 45 | 46 | - **source plaintext** : 47 | Plaintext to encrypt 48 | 49 | ## Steps 50 | 51 | 1. Define encryption context. 52 | 53 | ```python 54 | # Prepare your encryption context. 55 | # Remember that your encryption context is NOT SECRET. 56 | # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context 57 | encryption_context = { 58 | "encryption": "context", 59 | "is not": "secret", 60 | "but adds": "useful metadata", 61 | "that can help you": "be confident that", 62 | "the data you are handling": "is what you think it is", 63 | } 64 | ``` 65 | 66 | 1. Generate the wrapping key. 67 | 68 | ```python 69 | # Generate an RSA private key to use with your keyring. 70 | # In practice, you should get this key from a secure key management system such as an HSM. 71 | # 72 | # The National Institute of Standards and Technology (NIST) recommends a minimum of 2048-bit keys for RSA. 73 | # https://www.nist.gov/publications/transitioning-use-cryptographic-algorithms-and-key-lengths 74 | # 75 | # Why did we use this public exponent? 76 | # https://crypto.stanford.edu/~dabo/pubs/papers/RSA-survey.pdf 77 | private_key = rsa.generate_private_key(public_exponent=65537, key_size=4096, backend=default_backend()) 78 | ``` 79 | 80 | 1. Create keyring. 81 | 82 | ```python 83 | # Create the keyring that determines how your data keys are protected. 84 | keyring = RawRSAKeyring( 85 | # The key namespace and key name are defined by you 86 | # and are used by the raw RSA keyring 87 | # to determine whether it should attempt to decrypt 88 | # an encrypted data key. 89 | # 90 | # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-rsa-keyring 91 | key_namespace="some managed raw keys", 92 | key_name="my RSA wrapping key", 93 | private_wrapping_key=private_key, 94 | public_wrapping_key=private_key.public_key(), 95 | # The wrapping algorithm tells the raw RSA keyring 96 | # how to use your wrapping key to encrypt data keys. 97 | # 98 | # We recommend using RSA_OAEP_SHA256_MGF1. 99 | # You should not use RSA_PKCS1 unless you require it for backwards compatibility. 100 | wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1, 101 | ) 102 | ``` 103 | 104 | 1. Encrypt plaintext data. 105 | 106 | ```python 107 | # Encrypt your plaintext data. 108 | ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( 109 | source=source_plaintext, encryption_context=encryption_context, keyring=keyring 110 | ) 111 | ``` 112 | 113 | 1. Compare ciphertext to plaintext. 114 | 115 | ```python 116 | # Demonstrate that the ciphertext and plaintext are different. 117 | assert ciphertext != source_plaintext 118 | ``` 119 | 120 | 1. Decrypt encrypted data. 121 | 122 | ```python 123 | # Decrypt your encrypted data using the same keyring you used on encrypt. 124 | # 125 | # You do not need to specify the encryption context on decrypt 126 | # because the header of the encrypted message includes the encryption context. 127 | decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, keyring=keyring) 128 | ``` 129 | 130 | 1. Compare the decrypted plaintext and original plaintext. 131 | 132 | ```python 133 | # Demonstrate that the decrypted plaintext is identical to the original plaintext. 134 | assert decrypted == source_plaintext 135 | ``` 136 | 137 | 1. Verify the encryption context. 138 | 139 | ```python 140 | # Verify that the encryption context used in the decrypt operation includes 141 | # the encryption context that you specified when encrypting. 142 | # The AWS Encryption SDK can add pairs, so don't require an exact match. 143 | # 144 | # In production, always use a meaningful encryption context. 145 | assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items()) 146 | ``` 147 | -------------------------------------------------------------------------------- /examples/templates/readme.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Examples Section Readme 5 | 6 | ## Version 7 | 8 | 0.1.0 9 | 10 | ### Changelog 11 | 12 | - 0.1.0 13 | 14 | - [Require examples](../../changes/2020-06-16_required-examples/change.md) 15 | 16 | ## Implementations 17 | 18 | - [Python (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/README.md) 19 | - [Java (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/README.md) 20 | 21 | ## Overview 22 | 23 | Every implementation MUST include a readme 24 | that introduces all examples 25 | and identifies which use-cases 26 | map to which examples. 27 | 28 | ## Definitions 29 | 30 | ### Conventions used in this document 31 | 32 | The key words 33 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 34 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 35 | in this document are to be interpreted as described in 36 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 37 | 38 | ## Requirements 39 | 40 | The readme MUST contain the following information: 41 | 42 | 1. A listing of each [API example](./api) 43 | with a short description of the use-case 44 | and a link to the example. 45 | 1. A listing of each [configuration example](./configuration) 46 | with a short description of the use-case 47 | and a link to the example. 48 | 1. Instructions for developers writing examples 49 | that describe any requirements 50 | (organization/layout/naming/etc) 51 | and any actions that need to be taken 52 | to make sure the continuous integration testing 53 | tests the new examples. 54 | -------------------------------------------------------------------------------- /framework/README.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Material Providers Library 5 | 6 | ## Overview 7 | 8 | This repository contains the Material Providers Library Specification. 9 | The primary goal of this specification is to define a standard, 10 | language independent, description of the Material Providers Library features. 11 | It serves as the source of truth for the features that make up the Material Providers Library 12 | and the details of their behavior. 13 | 14 | It is intended to promote consistency and interoperability 15 | across implementations of the Material Providers Library. 16 | It also is intended to promote consistency, interoperability, and ease of configuration 17 | across AWS Cryptography Crypto Tools libraries. 18 | By offering a consistency configuration story 19 | this simplifies our documentation 20 | and makes it easier for our customers to use AWS Cryptography Crypto Tools libraries 21 | to actually encrypt/decrypt. 22 | 23 | This GitHub project is also intended to track issues and feature requests, 24 | and to collect feedback pertaining to the Material Providers Library. 25 | As well as potential needs for other AWS Cryptography Crypto Tools libraries. 26 | 27 | [Security issue notifications](./CONTRIBUTING.md#security-issue-notifications) 28 | 29 | ## License Summary 30 | 31 | The documentation is made available under the Creative Commons Attribution-ShareAlike 4.0 International License. 32 | See the LICENSE file. 33 | 34 | The sample code within this documentation is made available under the MIT-0 license. 35 | See the LICENSE-SAMPLECODE file. 36 | 37 | ## Editing 38 | 39 | We use `prettier` to maintain consistent formatting. 40 | Our CI will stop PRs that do not match our formatting requirements, 41 | but to easily apply them, 42 | run `../ci/prettify.sh write`. 43 | If you want to check them without writing, 44 | run `../ci/prettify.sh check`. 45 | -------------------------------------------------------------------------------- /framework/aws-kms/aws-kms-discovery-keyring.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # AWS KMS Discovery Keyring 5 | 6 | ## Version 7 | 8 | 0.3.0 9 | 10 | ### Changelog 11 | 12 | - 0.3.0 13 | 14 | - Incorporate [KMS Keyring Redesign](https://github.com/awslabs/aws-encryption-sdk-specification/tree/master/proposals/2020-07-01_aws-kms-keyring-redesign) 15 | 16 | - 0.2.2 17 | 18 | - Rename Key IDs to Key Names for increased clarity 19 | - Update Key Names and Generator sections to reinforce support for all AWS KMS key identifiers 20 | - [Pull request link for discussions](https://github.com/awslabs/aws-encryption-sdk-specification/pull/123) 21 | 22 | - 0.2.1 23 | 24 | - [Clarify naming of KMS to AWS KMS](https://github.com/awslabs/aws-encryption-sdk-specification/issues/67) 25 | 26 | - 0.2.0 27 | 28 | - [Remove Keyring Trace](../changes/2020-05-13_remove-keyring-trace/change.md) 29 | 30 | - 0.1.0-preview 31 | 32 | - Initial record 33 | 34 | ## Implementations 35 | 36 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 37 | | -------- | -------------------------------------- | ------------------------- | -------------- | 38 | 39 | ## Overview 40 | 41 | A keyring which interacts with AWS Key Management Service (AWS KMS) 42 | to decrypt data keys using a filter to identify Customer Master Keys (CMKs). 43 | 44 | ## Definitions 45 | 46 | ### Conventions used in this document 47 | 48 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 49 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 50 | 51 | ## Interface 52 | 53 | MUST implement that [AWS Encryption SDK Keyring interface](../keyring-interface.md#interface) 54 | 55 | ## Initialization 56 | 57 | On initialization the caller MUST provide: 58 | 59 | - An AWS KMS client 60 | - An optional discovery filter that is an AWS partition and a set of AWS accounts 61 | - An optional list of AWS KMS grant tokens 62 | 63 | The AWS KMS SDK client MUST NOT be null. 64 | 65 | ## OnEncrypt 66 | 67 | This function MUST fail. 68 | 69 | ## OnDecrypt 70 | 71 | OnDecrypt MUST take [decryption materials](../structures.md#decryption-materials) and 72 | a list of [encrypted data keys](../structures.md#encrypted-data-key) as input. 73 | 74 | If the [decryption materials](../structures.md#decryption-materials) already contained a valid plaintext data key, 75 | they keyring MUST fail and MUST NOT modify the [decryption materials](../structures.md#decryption-materials). 76 | 77 | The set of encrypted data keys MUST first be filtered to match this keyring’s configuration. 78 | For the encrypted data key to match 79 | 80 | - Its provider ID MUST exactly match the value “aws-kms”. 81 | - The provider info MUST be a [valid AWS KMS ARN](aws-kms-key-arn.md#a-valid-aws-kms-arn) with a resource type of `key` or OnDecrypt MUST fail. 82 | - If a discovery filter is configured, its partition and the provider info partition MUST match. 83 | - If a discovery filter is configured, its set of accounts MUST contain the provider info account. 84 | 85 | For each encrypted data key in the filtered set, one at a time, the OnDecrypt MUST attempt to decrypt the data key. If this attempt results in an error, then these errors are collected. 86 | 87 | To attempt to decrypt a particular [encrypted data key](../structures.md#encrypted-data-key), 88 | OnDecrypt MUST call [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) with the configured AWS KMS client. 89 | 90 | When calling [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html), the keyring MUST call with a request constructed as follows: 91 | 92 | - `KeyId`: The AWS KMS ARN from the provider info 93 | - `CiphertextBlob`: The [encrypted data key ciphertext](../structures.md#ciphertext). 94 | - `EncryptionContext`: The [encryption context](../structures.md#encryption-context) included in the input [decryption materials](../structures.md#decryption-materials). 95 | - `GrantTokens`: this keyring's [grant tokens](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token) 96 | 97 | If the call to [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) succeeds OnDecrypt verifies 98 | 99 | - The `KeyId` field in the response MUST equal the AWS KMS ARN from the provider info 100 | - The length of the response’s `Plaintext` MUST equal the [key derivation input length](../algorithm-suites.md#key-derivation-input-length) 101 | specified by the [algorithm suite](../algorithm-suites.md) included in the input [decryption materials](../structures.md#decryption-materials). 102 | 103 | If the response does not satisfy these requirements 104 | then an error is collected and the next encrypted data key in the filtered set MUST be attempted. 105 | 106 | If the response does satisfy these requirements then OnDecrypt MUST do the following with the response: 107 | 108 | - set the plaintext data key on the [decryption materials](../structures.md#decryption-materials) as the response `Plaintext`. 109 | - immediately return the modified [decryption materials](../structures.md#decryption-materials). 110 | 111 | If OnDecrypt fails to successfully decrypt any [encrypted data key](../structures.md#encrypted-data-key), 112 | then it MUST yield an error that includes all collected errors. 113 | -------------------------------------------------------------------------------- /framework/aws-kms/aws-kms-key-arn.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # AWS KMS Key ARN 5 | 6 | ## Version 7 | 8 | 0.2.2 9 | 10 | ### Changelog 11 | 12 | - 0.2.2 13 | 14 | - Initial record 15 | 16 | ## Implementations 17 | 18 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 19 | | -------- | -------------------------------------- | ------------------------- | -------------- | 20 | 21 | ## Overview 22 | 23 | AWS KMS Key ARNs generally follow [AWS ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)) 24 | but there are a few subtle differences. 25 | This is NOT the authoritative source for these rules, 26 | it is just a specification for how the ESDK processes AWS KMS CMK ARNs. 27 | 28 | ## Definitions 29 | 30 | ### Conventions used in this document 31 | 32 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 33 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 34 | 35 | ## A valid AWS KMS ARN 36 | 37 | A string with 5 `:` that delimit following 6 parts: 38 | 39 | 1. MUST start with string `arn` 40 | 2. The partition MUST be a non-empty 41 | 3. The service MUST be the string `kms` 42 | 4. The region MUST be a non-empty string 43 | 5. The account MUST be a non-empty string 44 | 6. The resource section MUST be non-empty and MUST be split by a single `/` 45 | any additional `/` are included in the resource id 46 | 1. The resource type MUST be either `alias` or `key` 47 | 2. The resource id MUST be a non-empty string 48 | 49 | ## A valid AWS KMS identifier 50 | 51 | An AWS KMS identifer can be any of the following 52 | 53 | - A valid AWS KMS ARN 54 | - AWS KMS alias, the resource section of an AWS KMS alias ARN 55 | - AWS KMS key id, the resource id of an AWS KMS key ARN 56 | 57 | ## AWS KMS multi-Region keys 58 | 59 | AWS KMS multi-Region keys can be distinguished from a single-Region key because the key id begins with `mrk-`. 60 | AWS KMS MRK aware components can take as input any AWS KMS identifier: 61 | 62 | - AWS KMS key ARN (`arn:aws:kms:us-east-1:2222222222222:key/1234abcd-12ab-34cd-56ef-1234567890ab`) 63 | - AWS KMS multi-Region key ARN (`arn:aws:kms:us-east-1:2222222222222:key/mrk-4321abcd12ab34cd56ef1234567890ab`) 64 | - AWS KMS alias ARN (`arn:aws:kms:us-west-2:111122223333:alias/test-key`) 65 | - AWS KMS key id (`1234abcd-12ab-34cd-56ef-1234567890ab`) 66 | - AWS KMS multi-Region key id (`mrk-4321abcd12ab34cd56ef1234567890ab`) 67 | - AWS KMS alias (`alias/test-key`) 68 | 69 | Since the alias is can be any string a customer can create an alias that started with `mrk-`. 70 | But an alias is not a multi-Region key. 71 | 72 | ## Identifying an an AWS KMS multi-Region ARN 73 | 74 | This function MUST take a single AWS KMS ARN 75 | 76 | If the input is an invalid AWS KMS ARN this function MUST error. 77 | 78 | If resource type is “alias”, 79 | this is an AWS KMS alias ARN and MUST return false. 80 | If resource type is “key” and resource ID starts with “mrk-“, 81 | this is a AWS KMS multi-Region key ARN and MUST return true. 82 | If resource type is “key” and resource ID does not start with “mrk-“, 83 | this is a (single-region) AWS KMS key ARN and MUST return false. 84 | 85 | ## Identifying an an AWS KMS multi-Region identifier 86 | 87 | This function MUST take a single AWS KMS identifier 88 | 89 | If the input starts with "arn:", 90 | this MUST return the output of [identifying an an AWS KMS multi-Region ARN](aws-kms-key-arn.md#identifying-an-an-aws-kms-multi-region-arn) 91 | called with this input. 92 | If the input starts with “alias/“, 93 | this an AWS KMS alias and not a multi-Region key id and MUST return false. 94 | If the input starts with “mrk-“, 95 | this is a multi-Region key id and MUST return true. 96 | If the input does not start with any of the above, 97 | this is not a multi-Region key id and MUST return false. 98 | -------------------------------------------------------------------------------- /framework/aws-kms/aws-kms-mrk-are-unique.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Assert AWS KMS MRK are unique 5 | 6 | ## Version 7 | 8 | 0.2.2 9 | 10 | ### Changelog 11 | 12 | - 0.2.2 13 | 14 | - Initial record 15 | 16 | ## Implementations 17 | 18 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 19 | | -------- | -------------------------------------- | ------------------------- | -------------- | 20 | 21 | ## Overview 22 | 23 | Duplicate multi-region key ids create ambiguity about which Region to contact. 24 | This is better resolved outside of the AWS Encryption SDK. 25 | While preferring the "local" Region is a seductive solution, 26 | this can not be 100% correct. 27 | First, because not all code runs in an AWS Region, 28 | and second because customers may want create privacy controls around their data. 29 | In this case nearby region may exists and store ciphertext, 30 | but may be restricted from having the AWS KMS keys. 31 | In any complicated deployment determining the closest, 32 | or preferred region is itself a complicated task. 33 | It will be easier for customers to reason about this criteria 34 | and ensure their code is correct 35 | if the AWS Encryption SDK offers one and only one configuration for a behavior. 36 | e.g. If the preferred region logic results in an ambiguous configuration 37 | is informed and they can resolve the ambiguity. 38 | Rather than attempting to resolve it ourselves. 39 | 40 | Preferring the local region does not suffice: 41 | not all code runs in an AWS Region boundary, 42 | and customers need to assert intentions to use a region. 43 | 44 | ## Definitions 45 | 46 | ### Conventions used in this document 47 | 48 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 49 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 50 | 51 | ## Implementation 52 | 53 | The caller MUST provide: 54 | 55 | - A list of AWS KMS key identifiers 56 | 57 | If the list does not contain any [multi-Region keys](aws-kms-key-arn.md#identifying-an-aws-kms-multi-region-key) 58 | this function MUST exit successfully. 59 | 60 | If there are zero duplicate resource ids between the multi-region keys, 61 | this function MUST exit successfully 62 | 63 | If any duplicate multi-region resource ids exist, 64 | this function MUST yield an error 65 | that includes all identifiers with duplicate resource ids 66 | not only the first duplicate found. 67 | -------------------------------------------------------------------------------- /framework/aws-kms/aws-kms-mrk-aware-master-key.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # AWS KMS MRK Aware Master Key 5 | 6 | ## Version 7 | 8 | 0.2.2 9 | 10 | ### Changelog 11 | 12 | - 0.2.2 13 | 14 | - Initial record 15 | 16 | ## Implementations 17 | 18 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 19 | | -------- | -------------------------------------- | ------------------------- | -------------- | 20 | 21 | ## Overview 22 | 23 | A Master Key which interacts with AWS Key Management Service (AWS KMS) 24 | to create, encrypt, and decrypt data keys 25 | using AWS KMS defined Customer Master Keys (CMKs). 26 | 27 | ## Definitions 28 | 29 | ### Conventions used in this document 30 | 31 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 32 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 33 | 34 | ## Interface 35 | 36 | MUST implement the [Master Key Interface](../master-key-interface.md#interface) 37 | 38 | ## Initialization 39 | 40 | On initialization, the caller MUST provide: 41 | 42 | - An AWS KMS key identifier 43 | - An AWS KMS SDK client. 44 | 45 | The AWS KMS key identifier MUST NOT be null or empty. 46 | The AWS KMS key identifier MUST be [a valid identifier](aws-kms-key-arn.md#a-valid-aws-kms-identifier). 47 | The AWS KMS SDK client MUST not be null. 48 | The master key MUST be able to be configured with an optional list of Grant Tokens. This configuration SHOULD be on initialization and SHOULD be immutable. 49 | 50 | ## Get Master Key 51 | 52 | MUST be unchanged from the Master Key interface. 53 | 54 | ## Get Master Keys For Encryption 55 | 56 | MUST be unchanged from the Master Key interface. 57 | 58 | ## Decrypt Data Key 59 | 60 | The inputs MUST be the same as the [Master Key Decrypt Data Key](../master-key-interface.md#decrypt-data-key) interface. 61 | 62 | The set of encrypted data keys MUST first be filtered to match this master key’s configuration. 63 | To match the encrypted data key’s provider ID MUST exactly match the value “aws-kms” 64 | and the the function [AWS KMS MRK Match for Decrypt](aws-kms-mrk-match-for-decrypt.md#implementation) called with the configured AWS KMS key identifier 65 | and the encrypted data key’s provider info MUST return `true`. 66 | Additionally each provider info MUST be a [valid AWS KMS ARN](aws-kms-key-arn.md#a-valid-aws-kms-arn) with a resource type of `key`. 67 | 68 | For each encrypted data key in the filtered set, one at a time, 69 | the master key MUST attempt to decrypt the data key. If this attempt results in an error, 70 | then these errors MUST be collected. 71 | 72 | To decrypt the encrypted data key this master key MUST use the configured AWS KMS client 73 | to make an [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) request constructed as follows: 74 | 75 | - `KeyId`: The configured AWS KMS key identifier. 76 | - `CiphertextBlob`: The `ciphertext` from the encrypted data key. 77 | - `EncryptionContext`: The encryption context included in the input. 78 | - `GrantTokens`: The configured grant tokens. 79 | 80 | If the call succeeds then the response’s `KeyId` MUST be equal to the configured AWS KMS key identifier 81 | otherwise the function MUST collect an error. 82 | The response’s `Plaintext`’s length MUST equal the length required by the requested algorithm suite 83 | otherwise the function MUST collect an error. 84 | 85 | If the AWS KMS response satisfies the requirements then it MUST be use and this function MUST return 86 | and not attempt to decrypt any more encrypted data keys. 87 | 88 | If all the input encrypted data keys have been processed 89 | then this function MUST yield an error that includes all the collected errors. 90 | 91 | The output MUST be the same as the [Master Key Decrypt Data Key](../master-key-interface.md#decrypt-data-key) interface. 92 | 93 | ## Generate Data Key 94 | 95 | The inputs MUST be the same as the [Master Key Generate Data Key](../master-key-interface.md#generate-data-key) interface. 96 | This master key MUST use the configured AWS KMS client 97 | to make an [AWS KMS GenerateDatakey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) request constructed as follows: 98 | 99 | - `KeyId`: The configured AWS KMS key identifier. 100 | - `NumberOfBytes`: The key derivation input length specified by the algorithm suite included in the input. 101 | - `EncryptionContext`: The encryption context included in the input. 102 | - `GrantTokens`: The configured grant tokens. 103 | 104 | If the call succeeds the AWS KMS Generate Data Key response’s `Plaintext` MUST match the key derivation input length specified by the algorithm suite included in the input. The response’s `KeyId` MUST be valid. 105 | The response’s `Plaintext` MUST be the plaintext in the output. The response’s cipher text blob MUST be used as the returned as the ciphertext for the encrypted data key in the output. 106 | 107 | The output MUST be the same as the [Master Key Generate Data Key](../master-key-interface.md#generate-data-key) interface. 108 | 109 | ## Encrypt Data Key 110 | 111 | The inputs MUST be the same as the [Master Key Encrypt Data Key](../master-key-interface.md#encrypt-data-key) interface. 112 | The master key MUST use the configured AWS KMS client to make an [AWS KMS Encrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Encrypt.html) request constructed as follows: 113 | 114 | - `KeyId`: The configured AWS KMS key identifier. 115 | - `PlaintextDataKey`: The plaintext data key obtained from the input. 116 | - `EncryptionContext`: the encryption context included in the input. 117 | - `GrantTokens`: The configured grant tokens. 118 | 119 | The AWS KMS Encrypt response MUST contain a valid `KeyId`. 120 | The response’s cipher text blob MUST be used as the `ciphertext` for the encrypted data key. 121 | 122 | The output MUST be the same as the [Master Key Encrypt Data Key](../master-key-interface.md#encrypt-data-key) interface. 123 | -------------------------------------------------------------------------------- /framework/aws-kms/aws-kms-mrk-discovery-keyring.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # AWS KMS MRK Discovery Keyring 5 | 6 | ## Version 7 | 8 | 0.2.2 9 | 10 | ### Changelog 11 | 12 | - 0.2.2 13 | 14 | - Initial record 15 | 16 | ## Implementations 17 | 18 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 19 | | -------- | -------------------------------------- | ------------------------- | -------------- | 20 | 21 | ## Overview 22 | 23 | A keyring which interacts with AWS Key Management Service (AWS KMS) 24 | to decrypt data keys using a filter to identify Customer Master Keys (CMKs). 25 | 26 | ## Definitions 27 | 28 | ### Conventions used in this document 29 | 30 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 31 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 32 | 33 | ## Interface 34 | 35 | MUST implement that [AWS Encryption SDK Keyring interface](../keyring-interface.md#interface) 36 | 37 | ## Initialization 38 | 39 | On initialization the keyring MUST accept the following parameters: 40 | 41 | - A required AWS KMS client 42 | - A required string indicating the region of the KMS client 43 | - An optional discovery filter that is an AWS partition and a set of AWS accounts 44 | - An optional list of AWS KMS grant tokens 45 | 46 | They keyring MUST fail initialization if any required parameters are missing or null. 47 | The keyring SHOULD fail initialization if the provided region does not match the 48 | region of the KMS client. Note that in some implementations this may not be 49 | possible, as some AWS SDKs may not provide an API to access this information. 50 | 51 | ## OnEncrypt 52 | 53 | This function MUST fail. 54 | 55 | ## OnDecrypt 56 | 57 | OnDecrypt MUST take [decryption materials](../structures.md#decryption-materials) and 58 | a list of [encrypted data keys](../structures.md#encrypted-data-key) as input. 59 | 60 | If the [decryption materials](../structures.md#decryption-materials) already contained a valid plaintext data key, 61 | they keyring MUST fail and MUST NOT modify the [decryption materials](../structures.md#decryption-materials). 62 | 63 | The set of encrypted data keys MUST first be filtered to match this keyring’s configuration. 64 | For the encrypted data key to match 65 | 66 | - Its provider ID MUST exactly match the value “aws-kms”. 67 | - The provider info MUST be a [valid AWS KMS ARN](aws-kms-key-arn.md#a-valid-aws-kms-arn) with a resource type of `key` or OnDecrypt MUST fail. 68 | - If a discovery filter is configured, its partition and the provider info partition MUST match. 69 | - If a discovery filter is configured, its set of accounts MUST contain the provider info account. 70 | - If the provider info is not [identified as a multi-Region key](aws-kms-key-arn.md#identifying-an-aws-kms-multi-region-key), then the provider info’s Region MUST match the AWS KMS client region. 71 | 72 | For each encrypted data key in the filtered set, one at a time, the OnDecrypt MUST attempt to decrypt the data key. If this attempt results in an error, then these errors are collected. 73 | 74 | To attempt to decrypt a particular [encrypted data key](../structures.md#encrypted-data-key), 75 | OnDecrypt MUST call [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) with the configured AWS KMS client. 76 | 77 | When calling [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html), the keyring MUST call with a request constructed as follows: 78 | 79 | - `KeyId`: If the provider info’s resource type is `key` and its resource is a multi-Region key 80 | then a new ARN MUST be created where the region part MUST equal the AWS KMS client region 81 | and every other part MUST equal the provider info. Otherwise it MUST be the provider info. 82 | - `CiphertextBlob`: The [encrypted data key ciphertext](../structures.md#ciphertext). 83 | - `EncryptionContext`: The [encryption context](../structures.md#encryption-context) included in the input [decryption materials](structures.md#decryption-materials). 84 | - `GrantTokens`: this keyring's [grant tokens](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token) 85 | 86 | If the call to [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) succeeds OnDecrypt verifies 87 | 88 | - The `KeyId` field in the response MUST equal the requested `KeyId` 89 | - The length of the response’s `Plaintext` MUST equal the [key derivation input length](../algorithm-suites.md#key-derivation-input-length) 90 | specified by the [algorithm suite](../algorithm-suites.md) included in the input [decryption materials](../structures.md#decryption-materials). 91 | 92 | If the response does not satisfies these requirements 93 | then an error is collected and the next encrypted data key in the filtered set MUST be attempted. 94 | 95 | Since the response does satisfies these requirements 96 | then OnDecrypt MUST do the following with the response: 97 | 98 | - set the plaintext data key on the [decryption materials](../structures.md#decryption-materials) as the response `Plaintext`. 99 | - immediately return the modified [decryption materials](../structures.md#decryption-materials). 100 | 101 | If OnDecrypt fails to successfully decrypt any [encrypted data key](../structures.md#encrypted-data-key), 102 | then it MUST yield an error that includes all collected errors. 103 | -------------------------------------------------------------------------------- /framework/aws-kms/aws-kms-mrk-match-for-decrypt.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # AWS KMS MRK Match for Decrypt 5 | 6 | ## Version 7 | 8 | 0.2.2 9 | 10 | ### Changelog 11 | 12 | - 0.2.2 13 | 14 | - Initial record 15 | 16 | ## Implementations 17 | 18 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 19 | | -------- | -------------------------------------- | ------------------------- | -------------- | 20 | 21 | ## Overview 22 | 23 | Since the AWS Encryption SDK stores the AWS KMS key ARN 24 | in the encrypted data key of the message format 25 | an AWS KMS component needs to be able to evaluate 26 | if a configured ARN matches a stored ARN. 27 | This is especially important for multi-Region keys because the match does not need to be exact. 28 | 29 | ## Definitions 30 | 31 | ### Conventions used in this document 32 | 33 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 34 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 35 | 36 | ## Implementation 37 | 38 | The caller MUST provide: 39 | 40 | - 2 AWS KMS key identifiers 41 | 42 | If both identifiers are identical, this function MUST return `true`. 43 | Otherwise if either input is not [identified as a multi-Region key](aws-kms-key-arn.md#identifying-an-aws-kms-multi-region-key), 44 | then this function MUST return `false`. 45 | Otherwise if both inputs are [identified as a multi-Region keys](aws-kms-key-arn.md#identifying-an-aws-kms-multi-region-key), 46 | this function MUST return the result of comparing 47 | the `partition`, `service`, `accountId`, `resourceType`, and `resource` parts of both ARN inputs. 48 | NOTE: The `region` part is intentionally omitted. 49 | -------------------------------------------------------------------------------- /framework/aws-kms/aws-kms-mrk-multi-keyrings.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # AWS KMS MRK Multi Keyrings 5 | 6 | ## Version 7 | 8 | 0.2.2 9 | 10 | ### Changelog 11 | 12 | - 0.2.2 13 | 14 | - Initial record 15 | 16 | ## Implementations 17 | 18 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 19 | | -------- | -------------------------------------- | ------------------------- | -------------- | 20 | 21 | ## Overview 22 | 23 | The AWS KMS MRK keyrings only operate on a single AWS KMS key ARN. 24 | However customers want to easily configure multiple AWS KMS key ARNs. 25 | These functions compose multiple AWS KMS key ARNs and return a single Multi Keyring. 26 | 27 | ## Definitions 28 | 29 | ### Conventions used in this document 30 | 31 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 32 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 33 | 34 | Customers need a way to compose the single AWS KMS keyrings in an easy way. These functions take configuration and produce and compose many keyrings into a Multi Keyring. 35 | 36 | ## AWS KMS MRK Multi-Keyring 37 | 38 | The caller MUST provide: 39 | 40 | - An optional AWS KMS key identifiers to use as the generator. 41 | - An optional set of AWS KMS key identifiers to us as child keyrings. 42 | - An optional method that can take a region string and return an AWS KMS client e.g. a regional client supplier 43 | - An optional list of AWS KMS grant tokens 44 | 45 | If any of the AWS KMS key identifiers is not a [valid AWS KMS key ARN](aws-kms-key-arn.md#a-valid-aws-kms-arn), this function MUST fail 46 | All AWS KMS identifiers are passed to [Assert AWS KMS MRK are unique](aws-kms-mrk-are-unique.md#Implementation) 47 | and the function MUST return success otherwise this MUST fail. 48 | If a regional client supplier is not passed, then a default MUST be created that takes a region string and generates a default AWS SDK client for the given region. 49 | 50 | If there is a generator input then the generator keyring MUST be a [AWS KMS MRK Keyring](aws-kms-mrk-keyring.md) initialized with 51 | 52 | - The generator input. 53 | - The AWS KMS client that MUST be created by the regional client supplier 54 | when called with the region part of the generator ARN 55 | or a signal for the AWS SDK to select the default region. 56 | - The input list of AWS KMS grant tokens 57 | 58 | If there is a set of child identifiers then a set of [AWS KMS MRK Keyring](aws-kms-mrk-keyring.md) MUST be created for each AWS KMS key identifier by initialized each keyring with 59 | 60 | - AWS KMS key identifier. 61 | - The AWS KMS client that MUST be created by the regional client supplier 62 | when called with the region part of the AWS KMS key identifier 63 | or a signal for the AWS SDK to select the default region. 64 | - The input list of AWS KMS grant tokens 65 | 66 | NOTE: The AWS Encryption SDK SHOULD NOT attempt to evaluate its own default region. 67 | 68 | Then a [Multi-Keyring](../multi-keyring.md#inputs) MUST be initialize by using this generator keyring as the [generator keyring](../multi-keyring.md#generator-keyring) and this set of child keyrings as the [child keyrings](../multi-keyring.md#child-keyrings). 69 | This Multi-Keyring MUST be this functions output. 70 | 71 | ## AWS KMS MRK Discovery Multi-Keyring 72 | 73 | The caller MUST provide: 74 | 75 | - A set of Region strings 76 | - An optional discovery filter that is an AWS partition and a set of AWS accounts 77 | - An optional method that can take a region string and return an AWS KMS client e.g. a regional client supplier 78 | - An optional list of AWS KMS grant tokens 79 | 80 | If an empty set of Region is provided this function MUST fail. 81 | If any element of the set of regions is null or an empty string this function MUST fail. 82 | If a regional client supplier is not passed, then a default MUST be created that takes a region string and generates a default AWS SDK client for the given region. 83 | 84 | A set of AWS KMS clients MUST be created by calling regional client supplier for each region in the input set of regions. 85 | 86 | Then a set of [AWS KMS MRK Discovery Keyring](aws-kms-mrk-discovery-keyring.md) MUST be created for each AWS KMS client by initializing each keyring with 87 | 88 | - The AWS KMS client 89 | - The input discovery filter 90 | - The input AWS KMS grant tokens 91 | 92 | Then a [Multi-Keyring](../multi-keyring.md#inputs) MUST be initialize by using this set of discovery keyrings as the [child keyrings](../multi-keyring.md#child-keyrings). 93 | This Multi-Keyring MUST be this functions output. 94 | -------------------------------------------------------------------------------- /framework/aws-kms/aws-kms-multi-keyrings.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # AWS KMS Multi Keyrings 5 | 6 | ## Version 7 | 8 | 0.3.0 9 | 10 | ### Changelog 11 | 12 | - 0.3.0 13 | 14 | - Incorporate [KMS Keyring Redesign](https://github.com/awslabs/aws-encryption-sdk-specification/tree/master/proposals/2020-07-01_aws-kms-keyring-redesign) 15 | 16 | - 0.2.2 17 | 18 | - Rename Key IDs to Key Names for increased clarity 19 | - Update Key Names and Generator sections to reinforce support for all AWS KMS key identifiers 20 | - [Pull request link for discussions](https://github.com/awslabs/aws-encryption-sdk-specification/pull/123) 21 | 22 | - 0.2.1 23 | 24 | - [Clarify naming of KMS to AWS KMS](https://github.com/awslabs/aws-encryption-sdk-specification/issues/67) 25 | 26 | - 0.2.0 27 | 28 | - [Remove Keyring Trace](../../changes/2020-05-13_remove-keyring-trace/change.md) 29 | 30 | - 0.1.0-preview 31 | 32 | - Initial record 33 | 34 | ## Implementations 35 | 36 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 37 | | -------- | -------------------------------------- | ------------------------- | -------------- | 38 | 39 | ## Overview 40 | 41 | The AWS KMS MRK keyrings only operate on a single AWS KMS key ARN. 42 | However customers want to easily configure multiple AWS KMS key ARNs. 43 | These functions compose multiple AWS KMS key ARNs and return a single Multi Keyring. 44 | 45 | ## Definitions 46 | 47 | ### Conventions used in this document 48 | 49 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 50 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 51 | 52 | Customers need a way to compose the single AWS KMS keyrings in an easy way. These functions take configuration and produce and compose many keyrings into a Multi Keyring. 53 | 54 | ## AWS KMS Multi-Keyring 55 | 56 | The caller MUST provide: 57 | 58 | - An optional AWS KMS key identifiers to use as the generator. 59 | - An optional set of AWS KMS key identifiers to use as child keyrings. 60 | - An optional method that can take a region string and return an AWS KMS client e.g. a regional client supplier 61 | - An optional list of AWS KMS grant tokens 62 | 63 | If any of the AWS KMS key identifiers is not a [valid AWS KMS key ARN](aws-kms-key-arn.md#a-valid-aws-kms-arn), this function MUST fail. 64 | If a regional client supplier is not passed, then a default MUST be created that takes a region string and generates a default AWS SDK client for the given region. 65 | 66 | If there is a generator input then the generator keyring MUST be a [AWS KMS Keyring](aws-kms-keyring.md) initialized with 67 | 68 | - The generator input. 69 | - The AWS KMS client that MUST be created by the regional client supplier 70 | when called with the region part of the generator ARN 71 | or a signal for the AWS SDK to select the default region. 72 | - The input list of AWS KMS grant tokens 73 | 74 | If there is a set of child identifiers then a set of [AWS KMS Keyring](aws-kms-keyring.md) MUST be created for each AWS KMS key identifier by initializing each keyring with 75 | 76 | - AWS KMS key identifier. 77 | - The AWS KMS client that MUST be created by the regional client supplier 78 | when called with the region part of the AWS KMS key identifier 79 | or a signal for the AWS SDK to select the default region. 80 | - The input list of AWS KMS grant tokens 81 | 82 | NOTE: The AWS Encryption SDK SHOULD NOT attempt to evaluate its own default region. 83 | 84 | Then a [Multi-Keyring](../multi-keyring.md#inputs) MUST be initialize by using this generator keyring as the [generator keyring](../multi-keyring.md#generator-keyring) and this set of child keyrings as the [child keyrings](../multi-keyring.md#child-keyrings). 85 | This Multi-Keyring MUST be this function's output. 86 | 87 | ## AWS KMS Discovery Multi-Keyring 88 | 89 | The caller MUST provide: 90 | 91 | - A set of Region strings 92 | - An optional discovery filter that is an AWS partition and a set of AWS accounts 93 | - An optional method that can take a region string and return an AWS KMS client e.g. a regional client supplier 94 | - An optional list of AWS KMS grant tokens 95 | 96 | If an empty set of Region is provided this function MUST fail. 97 | If any element of the set of regions is null or an empty string this function MUST fail. 98 | If a regional client supplier is not passed, then a default MUST be created that takes a region string and generates a default AWS SDK client for the given region. 99 | 100 | A set of AWS KMS clients MUST be created by calling regional client supplier for each region in the input set of regions. 101 | 102 | Then a set of [AWS KMS Discovery Keyring](aws-kms-discovery-keyring.md) MUST be created for each AWS KMS client by initializing each keyring with 103 | 104 | - The AWS KMS client 105 | - The input discovery filter 106 | - The input AWS KMS grant tokens 107 | 108 | Then a [Multi-Keyring](../multi-keyring.md#inputs) MUST be initialize by using this set of discovery keyrings as the [child keyrings](../multi-keyring.md#child-keyrings). 109 | This Multi-Keyring MUST be this functions output. 110 | -------------------------------------------------------------------------------- /framework/key-store/default-key-storage.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Default Key Storage 5 | 6 | ## Version 7 | 8 | 0.1.0 9 | 10 | ### Changelog 11 | 12 | - 0.1.0 13 | - Initial record 14 | 15 | ## Overview 16 | 17 | The default key storage is [DynamoDB Key Storage](./dynamodb-key-storage.md#overview). 18 | -------------------------------------------------------------------------------- /framework/key-store/key-storage.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Key Storage 5 | 6 | ## Version 7 | 8 | 0.2.0 9 | 10 | ### Changelog 11 | 12 | - 0.2.0 13 | - [Mitigate Update Race in the Branch Key Store](../../changes/2025-01-16_key-store-mitigate-update-race/background.md) 14 | - 0.1.0 15 | - Initial record 16 | 17 | ## Implementations 18 | 19 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 20 | | -------- | -------------------------------------- | ------------------------- | -------------- | 21 | 22 | ## Overview 23 | 24 | Key Storage is the interface for customers to construct their own storage layer for the [key store](../branch-key-store.md#overview). 25 | This is useful to either customize how DynamoDB is used or stored, 26 | or to implement a custom storage system such as S3, 27 | or to consolidate keystore data access behind some remote micro-service. 28 | 29 | The key storage interface is not responsible for making sure that the encrypted keys are of the appropriate types. 30 | This is the responsibility of the wrapping key store. 31 | 32 | ## Definitions 33 | 34 | ### Conventions used in this document 35 | 36 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 37 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 38 | 39 | ### EncryptedHierarchicalKey 40 | 41 | An encrypted structure that holds an encrypted beacon or branch key. 42 | 43 | This structure MUST include all of the following fields: 44 | 45 | - [BranchKeyId](./structures.md#branch-key-id) 46 | - [Type](#type) 47 | - CreateTime: Timestamp in ISO 8601 format in UTC, to microsecond precision. 48 | - KmsArn: The AWS KMS Key ARN used to protect the CiphertextBlob value. 49 | - [EncryptionContext](./structures.md#encryption-context-3) 50 | - CiphertextBlob: The encrypted binary for the hierarchical key. 51 | 52 | ### Type 53 | 54 | A union that MUST hold the following three options 55 | 56 | - ActiveHierarchicalSymmetricVersion [ActiveHierarchicalSymmetric](#activehierarchicalsymmetric) 57 | - HierarchicalSymmetricVersion [HierarchicalSymmetric](#hierarchicalsymmetric) 58 | - ActiveHierarchicalSymmetricBeacon 59 | 60 | ### ActiveHierarchicalSymmetric 61 | 62 | A structure that MUST have one member, 63 | the UTF8 Encoded value of the version of the branch key. 64 | 65 | ### HierarchicalSymmetric 66 | 67 | A structure that MUST have one member, 68 | the UTF8 Encoded value of the version of the branch key. 69 | 70 | ### OverWriteEncryptedHierarchicalKey 71 | 72 | A structure that holds two related [EncryptedHierarchicalKeys](#encryptedhierarchicalkey): 73 | 74 | - Item: the [EncryptedHierarchicalKey](#encryptedhierarchicalkey) that will be written 75 | - Old: the [EncryptedHierarchicalKey](#encryptedhierarchicalkey) that was read and is presumed to be the currently persisted item that will be replaced by `Item`. 76 | 77 | ## Interface 78 | 79 | The KeyStorageInterface MUST support the following operations: 80 | 81 | - [WriteNewEncryptedBranchKey](#writenewencryptedbranchkey) 82 | - [WriteNewEncryptedBranchKeyVersion](#writenewencryptedbranchkeyversion) 83 | - [GetEncryptedActiveBranchKey](#getencryptedactivebranchkey) 84 | - [GetEncryptedBranchKeyVersion](#getencryptedbranchkeyversion) 85 | - [GetEncryptedBeaconKey](#getencryptedbeaconkey) 86 | - [GetKeyStorageInfo](#getkeystorageinfo) 87 | 88 | ### WriteNewEncryptedBranchKey 89 | 90 | The WriteNewEncryptedBranchKey caller MUST provide: 91 | 92 | - An [EncryptedHierarchicalKey](#encryptedhierarchicalkey) with a [type](#type) of ActiveHierarchicalSymmetricVersion 93 | - An [EncryptedHierarchicalKey](#encryptedhierarchicalkey) with a [type](#type) of HierarchicalSymmetricVersion 94 | - An [EncryptedHierarchicalKey](#encryptedhierarchicalkey) with a [type](#type) of ActiveHierarchicalSymmetricBeacon 95 | 96 | All three keys need to be written together with an atomic transactional write. 97 | See the [default key stores's write new key to store specification](./default-key-storage-interface.md#writenewencryptedbranchkey) for more details about what storage properties are expected. 98 | 99 | ### WriteNewEncryptedBranchKeyVersion 100 | 101 | The WriteNewEncryptedBranchKeyVersion caller MUST provide: 102 | 103 | - An [OverWriteEncryptedHierarchicalKey](#overwriteencryptedhierarchicalkey) with both `Item` and `Old` with [type](#type) of ActiveHierarchicalSymmetricVersion 104 | - An [EncryptedHierarchicalKey](#encryptedhierarchicalkey) with a [type](#type) of HierarchicalSymmetricVersion 105 | 106 | Both keys need to be written together with a consistent transactional write. 107 | See [default key stores's write new branch key version to store specification](./default-key-storage-interface.md#writenewencryptedbranchkeyversion) for more details about what storage properties are expected. 108 | 109 | ### GetEncryptedActiveBranchKey 110 | 111 | The GetEncryptedActiveBranchKey caller MUST provide the same inputs as the [GetActiveBranchKey](../branch-key-store.md#getactivebranchkey) operation. 112 | It MUST return an [EncryptedHierarchicalKey](#encryptedhierarchicalkey). 113 | 114 | ### GetEncryptedBranchKeyVersion 115 | 116 | The GetEncryptedBranchKeyVersion caller MUST provide the same inputs as the [GetBranchKeyVersion](../branch-key-store.md#getbranchkeyversion) operation. 117 | It MUST return an [EncryptedHierarchicalKey](#encryptedhierarchicalkey). 118 | 119 | ### GetEncryptedBeaconKey 120 | 121 | The GetEncryptedBeaconKey caller MUST provide the same inputs as the [GetBeaconKey](../branch-key-store.md#getbeaconkey) operation. 122 | It MUST return an [EncryptedHierarchicalKey](#encryptedhierarchicalkey). 123 | 124 | ### GetKeyStorageInfo 125 | 126 | It MUST return the physical table name. 127 | -------------------------------------------------------------------------------- /framework/master-key-interface.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Master Key Interface 5 | 6 | ## Version 7 | 8 | 0.1.0-preview 9 | 10 | ## Implementations 11 | 12 | - [Python](https://github.com/aws/aws-encryption-sdk-python/blob/master/src/aws_encryption_sdk/key_providers/base.py) 13 | - [Java](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/MasterKey.java) 14 | 15 | ## Overview 16 | 17 | Master keys are master key providers that only provide themselves. 18 | They also support generating and encrypting data keys. 19 | 20 | ### Legacy 21 | 22 | This is a legacy specification. 23 | Master keys SHOULD NOT be included in any additional implementations. 24 | Any new implementations MUST include [Keyrings](./keyring-interface.md) instead. 25 | 26 | ### Consistency 27 | 28 | This specification defines the common behavior between the two implementations 29 | that determine the REQUIRED functionality. 30 | 31 | Other specifics of behavior and API vary between the two implementations. 32 | 33 | ## Definitions 34 | 35 | ### Conventions used in this document 36 | 37 | The key words 38 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 39 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 40 | in this document are to be interpreted 41 | as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 42 | 43 | ## Interface 44 | 45 | ### Get Master Key 46 | 47 | Inputs and outputs are the same as for [master key providers](./master-key-provider-interface.md). 48 | 49 | A master key MUST supply itself and MUST NOT supply any other master keys. 50 | 51 | ### Get Master Keys For Encryption 52 | 53 | Inputs and outputs are the same as for [master key providers](./master-key-provider-interface.md). 54 | 55 | A master key MUST supply itself and MUST NOT supply any other master keys. 56 | 57 | ### Decrypt Data Key 58 | 59 | Inputs and outputs are the same as for [master key providers](./master-key-provider-interface.md). 60 | 61 | A master key SHOULD attempt to decrypt a data key using itself. 62 | 63 | A master key MUST not attempt to use any other master keys. 64 | 65 | ### Generate Data Key 66 | 67 | This interface is used to generate and encrypt a data key. 68 | 69 | The master key MUST generate a data key and MUST then encrypt that data key. 70 | 71 | Inputs to this interface MUST include 72 | the algorithm suite 73 | and the encryption context. 74 | 75 | The output of this interface MUST include 76 | the plaintext data key, 77 | the data key encrypted under the master key, 78 | and information that can identify which master key 79 | was used to generate and encrypt the data key. 80 | 81 | If the master key cannot generate or encrypt the data key, 82 | the call MUST result in an error. 83 | 84 | ### Encrypt Data Key 85 | 86 | This interface is used to encrypt a data key. 87 | 88 | The master key MUST encrypt the data key. 89 | 90 | Inputs to this interface MUST include 91 | the algorithm suite, 92 | the encryption context, 93 | the encrypted data key, 94 | and information that can identify which master key 95 | was used to encrypt the data key. 96 | 97 | The output of this interface MUST include 98 | a value that this master key can use to obtain 99 | the plaintext data key. 100 | Most commonly, 101 | this will be the result of an encryption operation. 102 | 103 | If the master key cannot encrypt the data key, 104 | the call MUST result in an error. 105 | -------------------------------------------------------------------------------- /framework/master-key-provider-interface.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Master Key Provider Interface 5 | 6 | ## Version 7 | 8 | 0.1.0-preview 9 | 10 | ## Implementations 11 | 12 | - [Python](https://github.com/aws/aws-encryption-sdk-python/blob/master/src/aws_encryption_sdk/key_providers/base.py) 13 | - [Java](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/MasterKeyProvider.java) 14 | 15 | ## Overview 16 | 17 | Master key providers are responsible for managing [master keys](./master-key-interface.md), 18 | determining which master keys should be used for encryption, 19 | and for decrypting data keys using available master keys. 20 | 21 | ### Legacy 22 | 23 | This is a legacy specification. 24 | Master key providers SHOULD NOT be included in any additional implementations. 25 | Any new implementations MUST include [Keyrings](./keyring-interface.md) instead. 26 | 27 | ### Consistency 28 | 29 | This specification defines the common behavior between the two implementations 30 | that determine the REQUIRED functionality. 31 | 32 | Other specifics of behavior and API vary between the two implementations. 33 | 34 | ## Definitions 35 | 36 | ### Conventions used in this document 37 | 38 | The key words 39 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 40 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 41 | in this document are to be interpreted 42 | as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 43 | 44 | ### Terms 45 | 46 | - Provider ID: A value that identifies a master key provider. 47 | This concept is equivalent to "key namespace" for Keyrings. 48 | - Key ID: A value that identifies a master key 49 | within the context of a master key provider. 50 | This concept is equivalent to "key name" for Keyrings. 51 | - Provider Info: The value that is written to a serialized encrypted data key 52 | that identifies a master key within the context of a master key provider. 53 | This MUST always be equal to the master key's key ID 54 | with the exception of the raw AES master key. 55 | For a detailed description of this exception, 56 | see the [Raw AES Keyring specification](./raw-aes-keyring.md). 57 | 58 | ## Interface 59 | 60 | ### Get Master Key 61 | 62 | This interface provides a way for a master key provider to return master keys. 63 | 64 | An implementation MUST support master key selection by key ID. 65 | 66 | An implementation MAY support master key selection by provider info or provider ID. 67 | 68 | The output of this interface MUST be a master key. 69 | 70 | If the master key provider cannot locate an appropriate master key, 71 | the call MUST result in an error. 72 | 73 | ### Get Master Keys For Encryption 74 | 75 | This interface provides a way for a master key provider to indicate which master keys 76 | SHOULD be used for encryption. 77 | 78 | Inputs to this interface MUST include the encryption context. 79 | 80 | Inputs MAY include the plaintext body and plaintext size. 81 | 82 | The output of this interface MUST include a list of all master keys that 83 | SHOULD be used for encryption. 84 | 85 | The output of this interface MUST indicate which one of those master keys 86 | MUST be used to generate the data key. 87 | 88 | ### Decrypt Data Key 89 | 90 | This interface is used to decrypt a data key. 91 | 92 | The master key provider SHOULD attempt to decrypt the data key 93 | by passing the request to any master keys that it has access to 94 | until it has either exhausted available master keys 95 | or obtained a plaintext data key. 96 | 97 | Inputs to this interface MUST include 98 | the algorithm suite, 99 | the encryption context, 100 | and a list of encrypted data keys. 101 | 102 | The output of this interface MUST include 103 | the decrypted data key 104 | and information that can identify which master key 105 | decrypted the data key. 106 | 107 | If the master key provider cannot decrypt the data key, 108 | the call MUST result in an error. 109 | -------------------------------------------------------------------------------- /framework/required-encryption-context-cmm.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Required Encryption Context Cryptographic Materials Manager 5 | 6 | ## Version 7 | 8 | 0.1.0 9 | 10 | ## Implementations 11 | 12 | | Language | Confirmed Compatible with Spec Version | Minimum Version Confirmed | Implementation | 13 | | -------- | -------------------------------------- | ------------------------- | -------------- | 14 | 15 | ## Overview 16 | 17 | Required Encryption Context Cryptographic Materials Manager (CMM) 18 | is a built-in CMM to add additional controls for Encryption Context. 19 | 20 | This CMM can be configured with a set of [encryption context](./structures.md#encryption-context) keys. 21 | This set of keys MUST 22 | 23 | - Exist in the encryption context of all [Encryption Materials Requests](./cmm-interface.md#encryption-materials-request). 24 | - Exist in the [required encryption context keys](./structures.md#required-encryption-context-keys) for returned [encryption materials](./structures.md#encryption-materials) 25 | so that these values will not be serialized into the [supported formats](./algorithm-suites.md#supported-formats). 26 | - Exist the reproduced encryption context of all [Decrypt Materials Requests](#decrypt-materials-request). 27 | 28 | ## Definitions 29 | 30 | ### Conventions used in this document 31 | 32 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 33 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 34 | 35 | ## Initialization 36 | 37 | On Required Encryption Context CMM initialization, 38 | the caller MUST provide the following values: 39 | 40 | - [Required Encryption Context Keys](#required-encryption-context-keys) 41 | 42 | Additionally, the caller MUST provide one of the following values: 43 | 44 | - [Underlying Cryptographic Materials Manager (CMM)](#underlying-cryptographic-materials-manager) 45 | - [Keyring](keyring-interface.md) 46 | 47 | If the caller provides a keyring, 48 | then the Required Encryption Context CMM MUST set its underlying CMM 49 | to a [default CMM](default-cmm.md) initialized with the keyring. 50 | 51 | ### Underlying Cryptographic Materials Manager 52 | 53 | The underlying [Cryptographic Materials Manager (CMM)](cmm-interface.md#supported-cmms) 54 | to query for encryption/decryption materials. 55 | 56 | ### Required Encryption Context Keys 57 | 58 | The set of encryption context keys to require 59 | in all [behaviors](#behaviors). 60 | 61 | ## Behaviors 62 | 63 | ### Get Encryption Materials 64 | 65 | The encryption context on the [encryption materials request](./cmm-interface.md#encryption-materials-request) 66 | MUST contain a value for every key in the configured [required encryption context keys](#required-encryption-context-keys) 67 | or this request MUST fail. 68 | 69 | The Required Encryption Context CMM MUST attempt to obtain [encryption materials](./structures.md#encryption-materials) 70 | by making a call to the [underlying CMM's](#underlying-cryptographic-materials-manager) 71 | [Get Encryption Materials](cmm-interface.md#get-encryption-materials). 72 | All configured [required encryption context keys](#required-encryption-context-keys) 73 | MUST exist in the required encryption context keys 74 | of the [encryption materials request](./cmm-interface.md#encryption-materials-request) 75 | to the [underlying CMM's](#underlying-cryptographic-materials-manager). 76 | 77 | The obtained [encryption materials](./structures.md#encryption-materials) MUST 78 | have all configured [required encryption context keys](#required-encryption-context-keys) 79 | in it's [required encryption context keys](./structures.md#required-encryption-context-keys). 80 | 81 | ### Decrypt Materials 82 | 83 | The reproduced encryption context on the [decrypt materials request](./cmm-interface.md#decrypt-materials-request) 84 | MUST contain a value for every key in the configured [required encryption context keys](#required-encryption-context-keys) 85 | or this request MUST fail. 86 | 87 | The Required Encryption Context 88 | CMM MUST attempt to obtain [decryption materials](./structures.md#decryption-materials) 89 | by making a call to the [underlying CMM's](#underlying-cryptographic-materials-manager) 90 | [decrypt materials](cmm-interface.md#decrypt-materials) interface 91 | with the unchanged [decrypt materials request](./cmm-interface.md#decrypt-materials-request). 92 | 93 | Since the CMM can modify the encryption context 94 | it is possible that the [underlying CMM's](#underlying-cryptographic-materials-manager) 95 | is not the DefaultCMM. 96 | In that case the [underlying CMM's](#underlying-cryptographic-materials-manager) 97 | might have removed [required encryption context keys](#required-encryption-context-keys) 98 | from the request forwarded to its keyring or underlying CMM. 99 | This would result in these values not being authenticated 100 | against the serialized message or even the plaintext data key. 101 | This would violate the CMM decryption contract. 102 | The obtained [decryption materials](./structures.md#decryption-materials) MUST 103 | have all configured [required encryption context keys](#required-encryption-context-keys) 104 | in it's [encryption context](./structures.md#encryption-context-2). 105 | -------------------------------------------------------------------------------- /framework/synchronized-local-cryptographic-materials-cache.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Synchronized Local Cryptographic Materials Cache 5 | 6 | ## Version 7 | 8 | ### Changelog 9 | 10 | - 0.1.0 11 | - Initial record 12 | - [Thread Safe Cache](../changes/2023-06-19_thread_safe_cache/change.md) 13 | 14 | ## Overview 15 | 16 | The synchronized local Cryptographic Materials Cache (synchronized local CMC) 17 | is a built-in implementation of the [CMC interface](cryptographic-materials-cache.md) 18 | provided by the AWS Encryption SDK. 19 | 20 | It provides thread safe access to a [Local CMC](local-cryptographic-materials-cache.md) 21 | 22 | ## Definitions 23 | 24 | ### Conventions used in this document 25 | 26 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 27 | in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). 28 | 29 | ## Initialization 30 | 31 | On initialization of the synchronized local CMC, 32 | the caller MUST provide exactly what is required by a 33 | [Local CMC](local-cryptographic-materials-cache.md). 34 | 35 | ## Behaviors 36 | 37 | All behaviors MUST be exactly the same as a [Local CMC](local-cryptographic-materials-cache.md), 38 | even if used in a multi-threaded context. 39 | -------------------------------------------------------------------------------- /framework/test-vectors/README.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | ## Summary 5 | 6 | These test vectors are intended to be used to validate interoperability 7 | across implementations of clients in a runtime, 8 | for the AWS Crypto Tools AWS Cryptographic Material Providers Library (MPL). 9 | 10 | They are composed of JSON manifest files that define one or more test cases, 11 | including sufficient information to process each test case. 12 | These manifest files can also identify additional resources needed for a given test case. 13 | These resources will be identified with a URI. 14 | If identifying a local file, the URI will be a relative path from the manifest file's 15 | parent directory to the target file. 16 | 17 | Every manifest type definition must include a unique type name that will be used by 18 | test vector handlers to identify the manifest type. 19 | 20 | See https://github.com/awslabs/aws-crypto-tools-test-vector-framework for additional information. 21 | This framework is much of the motivation for this work. 22 | 23 | The manifest is meant to produce encryption and decryption materials that every 24 | runtime implementation can process and produce the desired output for that test vector. 25 | 26 | These test vectors are not meant to be processed by a top level client library like 27 | the AWS Encryption SDK or the AWS Database Encryption SDK. However; they may be able 28 | to use the manifest to see how to construct keyrings that they can use in their test 29 | vectors. 30 | 31 | ```mermaid 32 | flowchart LR 33 | subgraph MPL Encryption-Materials 34 | direction LR 35 | MPL-Manifest --> MPL-Java -->|MPL-TestVector|EncryptionMaterials 36 | MPL-Manifest --> MPL-NET -->|MPL-TestVector|EncryptionMaterials 37 | MPL-Manifest --> MPL-X -->|MPL-TestVector|EncryptionMaterials 38 | end 39 | ``` 40 | 41 | ```mermaid 42 | flowchart LR 43 | subgraph MPL Decryption-Materials 44 | direction LR 45 | MPL-Manifest+MPL-TestVector --> MPL-Java -->|MPL-TestVector|DecryptionMaterials 46 | MPL-Manifest+MPL-TestVector --> MPL-NET -->|MPL-TestVector|DecryptionMaterials 47 | MPL-Manifest+MPL-TestVector --> MPL-X -->|MPL-TestVector|DecryptionMaterials 48 | end 49 | ``` 50 | 51 | ```mermaid 52 | flowchart LR 53 | subgraph ESDK Usage of MPL Manifest 54 | direction LR 55 | MPL-Manifest-. Keyring-Construction .-> ESDK-Java --> ESDK-Manifest 56 | 57 | MPL-Manifest-. Keyring-Construction .-> ESDK-NET --> ESDK-Manifest 58 | end 59 | ``` 60 | 61 | ## Glossary 62 | 63 | - **Test Vector** : Information about a single test case. Used to either process existing data 64 | or create new data. 65 | - **Test Vector Manifest** : A document that describes one or more test vectors. 66 | 67 | ## Out of Scope 68 | 69 | This file is not a definition or description of any specific type of test vector or manifest. 70 | 71 | ## Motivation 72 | 73 | The AWS Crypto Tools team has built several tools that require multiple implementations. 74 | Interoperability between these implementations and runtimes is critical. 75 | To ensure that these implementations are actually interoperable, 76 | we needed to define test vectors that would allow validation 77 | of various aspects of these tools. 78 | As we built more tools and required more types of test vectors, 79 | it became evident that there would be value in defining an extensible framework 80 | for defining many different types of test vectors to avoid having to reinvent the wheel 81 | for every client. 82 | 83 | We also need to be able to maintain backwards compatibility. 84 | By producing manifests that can be stored 85 | we can ensure that new clients can decrypt old messages. 86 | 87 | The latest version of the MPL being written in Dafny 88 | and much of the design requirements are proven by Dafny specifications. 89 | These specifications are valuable but having empirical tests 90 | makes this proof even stronger. 91 | Because you can write and prove a specification 92 | but it may not be correct. 93 | This is especially true for backwards compatibility. 94 | But even for code reviews and understanding the impact of a change, 95 | looking at how test vectors are created helps reason about the edge cases of a change. 96 | 97 | ## Drawbacks 98 | 99 | Not every configuration can be practically tested. 100 | See [test vector enumeration](test-vector-enumeration.md#selecting-a-representative-input-value) for details. 101 | 102 | We will need to write minimal clients in every language with which we want to use these test 103 | vectors to understand the manifests described in subsequent features. 104 | 105 | This should represent acceptable overhead: we would need to write some amount of code for each 106 | language to handle the test vectors anyway and this framework lets us define a consistent 107 | way of handling those test vectors while remaining simple to process. 108 | 109 | Additionally, using Dafny can lower this overhead. 110 | The challenge now is to compose the proper level of reusability. 111 | The MPL is the base library for many encryption clients 112 | and there may be some work to be able to reuse parts of these test vectors 113 | in other libraries. 114 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/README.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | ## Summary 5 | 6 | For each type of keyring or cmm description, 7 | there is a file that describes how this component is tested. 8 | This simplifies reasoning about each component. 9 | For example, to find out how the DefaultCMM is tested, 10 | look at the default-cmm.md file 11 | that describes how this component is tested 12 | and the various features that can be reasoned about. 13 | 14 | The test vectors MUST aggregate all these individual tests together 15 | into larger manifest files. 16 | 17 | Unless otherwise specified, all "Basic Tests" MUST use a `DefaultCMM` 18 | 19 | ## Motivation 20 | 21 | By keeping every component separate it is easier to find 22 | and reason about the completeness of testing. 23 | This also allows top level clients like the ESDK or DBESDK to 24 | reuse the key or cmm description to avoid reinventing the wheel. 25 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/default-cmm.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Default CMM Vectors 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Summary 11 | 12 | This describes the test cases for the [Default CMM](../../default-cmm.md) 13 | 14 | ## Reference-level Explanation 15 | 16 | ### Basic tests 17 | 18 | A test MUST verify that on both encrypt and decrypt the correct 19 | plaintext data key is produced. 20 | 21 | A test MUST verify that an encrypt keyring that returns 22 | an incorrect plaintext data key will fail. 23 | 24 | A test MUST verify that a decrypt keyring that returns 25 | an incorrect plaintext data key will fail. 26 | 27 | ### Required and reproduced encryption context success cases 28 | 29 | For a given [encryption context](../../structures.md#encryption-context), 30 | every subset of the keys for this encryption context 31 | MUST be attempted as the `requiredEncryptionContextKeys`. 32 | For example, `{ a: a, b: b }` produces the complete set of keys subsets: `{ {}, { a }, { b }, { a, b } }` called `requiredEncryptionContextKeys`. 33 | 34 | For every `requiredEncryptionContextKeys` produced above 35 | `reproducedEncryptionContext` MUST be attempted 36 | for every subset of the encryption context 37 | where the `requiredEncryptionContextKeys` is a subset of the attempted subset. 38 | 39 | For example: 40 | 41 | - Given an empty `requiredEncryptionContextKeys`, 42 | every combination of the original encryption context 43 | will succeed as `reproducedEncryptionContext`. 44 | - Given a `requiredEncryptionContextKeys` consisting of `{a}` the 45 | `reproducedEncryptionContext` to try would be: - `{ a : a }` and `{ a : a, b : b}` 46 | 47 | ### Required encryption context keys failures on encrypt 48 | 49 | For a given [encryption context](../../structures.md#encryption-context), 50 | every subset of the keys for this encryption context 51 | MUST be attempted as the `requiredEncryptionContextKeys`. 52 | The keys of the encryption context attempted however 53 | where the `requiredEncryptionContextKeys` MUST NOT be a subset of the attempted subset. 54 | 55 | For example: 56 | 57 | - Given an `encryptionContext`: `{a:a, b:b, c:c}` will produce the subset 58 | of `requiredEncryptionContextKeys`, `{{}, {a}, {b}, {c}, {a,b}, {a,c), {b,c}, {a,b,c}}` 59 | - Given a `requiredEncryptionContextKeys` consisting of `{a}` the 60 | `reproducedEncryptionContext` to try would be: 61 | - `{b:b, c:c}` 62 | - Given a `requiredEncryptionContextKeys` consisting of `{a,b}` the 63 | `reproducedEncryptionContext` to try would be: 64 | - `{}`, `{c:c}`, and `{a:a, c:c}` 65 | - Given a `requiredEncryptionContextKeys` consisting of `{a,b,c}` the 66 | `reproducedEncryptionContext` to try would be: 67 | - `{}` 68 | 69 | ### Reproduced encryption context failures on decrypt 70 | 71 | For a given [encryption context](../../structures.md#encryption-context), 72 | every subset of the keys for this encryption context 73 | MUST be attempted as the `requiredEncryptionContextKeys`. 74 | An incorrect encryption context 75 | MUST be attempted that differs from the correct encryption context 76 | by both values and keys. 77 | 78 | For example given the encryption context `{ a: a, b: b }`, 79 | all possible combinations that are not empty of `{ a: c, b: c, c: c}`. 80 | The test MUST attempt the union of every incorrect encryption context 81 | with every subset of the original encryption context. 82 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/encryption-context.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Encryption Context Vectors 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Summary 11 | 12 | This is a description of the standard encryption contexts to test. 13 | 14 | ## Reference-level Explanation 15 | 16 | ### Standard Encryption Contexts Constraints 17 | 18 | - MUST have an empty map. 19 | - The number of the items in the empty map MUST equal 0. 20 | - MUST have a small map. 21 | - The number of the items in the small map MUST be between 1 and 10. 22 | - MUST have a large map. 23 | - The number of the items in the large map MUST be greater than 10. 24 | - MUST have multibyte UTF8 characters in both the key and value. 25 | - MUST have multibyte non-BMP characters in both the key and value. 26 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/hierarchy.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Aws Kms Hierarchical Keyring Vectors 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Summary 11 | 12 | This describes the test cases for the [Aws Kms Hierarchical Keyring](../../aws-kms/aws-kms-hierarchical-keyring.md) 13 | 14 | ## Reference-level Explanation 15 | 16 | ### Basic tests 17 | 18 | For a given static branch key, 19 | a test MUST attempt to encrypt and decrypt 20 | with every available [algorithm suite](../../algorithm-suites.md#algorithm-suite-id) 21 | 22 | For every available algorithm suite and static branch key, 23 | a test MUST attempt to encrypt and decrypt with every [standard encryption context](./encryption-context.md#standard-encryption-contexts). 24 | 25 | ### Input dimensions 26 | 27 | #### Encrypt 28 | 29 | - key description 30 | - key: range of [representative branch keys](#representative-branch-keys) 31 | 32 | #### Decrypt 33 | 34 | - key description 35 | - key: range of [representative branch keys](#representative-branch-keys) 36 | - logicalKeyStore: 37 | - "Default", 38 | - Represents the logical key store name on encrypt 39 | - "Other" 40 | - Represents any other logical key store name 41 | 42 | ### Representative branch keys 43 | 44 | - `"static-branch-key-1"` 45 | - MUST be some valid branch key. 46 | - `"static-branch-key-2"` 47 | - MUST be some valid branch key other than `static-branch-key-1`. 48 | - `"branch-key-no-permissions"` 49 | - MUST be some valid branch key where the test vector runner does not have permissions for the KMS key. 50 | - `"branch-key-not-in-table"` 51 | - MUST be some branch key ID not present in the keystore table., 52 | - `"branch-key-no-version"` 53 | - MUST be some branch key that is in the table, but the configured version is not in the table. 54 | - `"invalid-branch-key-material"` 55 | - MUST be some branch key with illegally mutated invalid branch key material. 56 | 57 | ### Evaluation rules 58 | 59 | - If encrypting key type is anything other than `"aws-kms-hierarchy"` 60 | and decrypting key type is `"aws-kms-hierarchy"`, 61 | the result MUST be `"negative-decrypt"`. 62 | - If encrypting key type is `"aws-kms-hierarchy"` 63 | and decrypting key type is anything other than `"aws-kms-hierarchy"`, 64 | the result MUST be `"negative-decrypt"`. 65 | - If the logical key store is "Other", 66 | the result MUST be `"negative-decrypt"`. 67 | - If `"key"` is different on encrypt and decrypt, 68 | the result MUST be `"negative-decrypt"`. 69 | (i.e. no key specified here is interoperable with any other key.) 70 | - If `"key"` is any of: 71 | - `"branch-key-no-permissions"` 72 | - `"branch-key-not-in-table"` 73 | - `"branch-key-no-version"` 74 | - `"invalid-branch-key"` 75 | (i.e. an "invalid" key with a particular invalid condition) 76 | on either encrypt or decrypt, 77 | the result MUST be either `"negative-encrypt"` or `"negative-decrypt"`, 78 | depending on whether the invalid key was specified on encrypt or decrypt. 79 | - In all other cases, the result MUST be `"positive"`. 80 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/kms-mrk-aware-discovery.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Aws Kms Mrk Discovery Keyring Vectors 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Summary 11 | 12 | This describes the test cases for the [Aws Kms Mrk Discovery Keyring](../../aws-kms/aws-kms-mrk-discovery-keyring.md) 13 | 14 | ## Reference-level Explanation 15 | 16 | ### Basic tests 17 | 18 | A test MUST attempt to encrypt with a single region key. 19 | A test MUST attempt to encrypt with a multi region key. 20 | A test MUST attempt to decrypt with a discovery filter and without a filter. 21 | A test MUST attempt to encrypt and decrypt 22 | with every available [algorithm suite](../../algorithm-suites.md#algorithm-suite-id) 23 | A test MUST attempt every [standard encryption context](./encryption-context.md#standard-encryption-contexts). 24 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/kms-mrk-aware.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Aws Kms Mrk Keyring Vectors 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Summary 11 | 12 | This describes the test cases for the [Aws Kms Mrk Keyring](../../aws-kms/aws-kms-mrk-keyring.md) 13 | 14 | ## Reference-level Explanation 15 | 16 | ### Basic tests 17 | 18 | A test MUST attempt to encrypt and decrypt 19 | with every combination of 2 MRKs in different regions. 20 | A test MUST attempt to decrypt with only one of the MRKs used 21 | to encrypt. 22 | A test MUST attempt to encrypt and decrypt 23 | with every available [algorithm suite](../../algorithm-suites.md#algorithm-suite-id) 24 | A test MUST attempt every [standard encryption context](./encryption-context.md#standard-encryption-contexts). 25 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/kms-rsa.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Aws Kms Rsa Keyring Vectors 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Summary 11 | 12 | This describes the test cases for the [Aws Kms Rsa Keyring](../../aws-kms/aws-kms-rsa-keyring.md) 13 | 14 | ## Reference-level Explanation 15 | 16 | ### Basic tests 17 | 18 | A test MUST attempt with every RSA EncryptionAlgorithmSpec. 19 | 20 | A test MUST attempt to encrypt and decrypt 21 | with every non-signing [algorithm suite](../../algorithm-suites.md#algorithm-suite-id). 22 | The Aws Kms Rsa Keyring does not support asymmetric signing 23 | because the encryption context can be changed. 24 | Because the public half of the RSA key is public. 25 | 26 | A test MUST attempt every [standard encryption context](./encryption-context.md#standard-encryption-contexts). 27 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/kms.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # AWS KMS Keyring Vectors 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Summary 11 | 12 | This describes the test cases for the [AWS KMS Keyring](../../aws-kms/aws-kms-keyring.md) 13 | 14 | ## Reference-level Explanation 15 | 16 | ### Basic tests 17 | 18 | A test MUST attempt both a single region key 19 | and a multi region key. 20 | A test MUST attempt to encrypt and decrypt 21 | with every available [algorithm suite](../../algorithm-suites.md#algorithm-suite-id) 22 | A test MUST attempt every [standard encryption context](./encryption-context.md#standard-encryption-contexts). 23 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/raw-aes.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Raw AES Keyring Vectors 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Summary 11 | 12 | This describes the test cases for the [Raw AES Keyring](../../raw-aes-keyring.md) 13 | 14 | ## Reference-level Explanation 15 | 16 | ## Definitions 17 | 18 | - positive key description: a [key description](../key-description.md) that when parsed and generated can produce 19 | valid encryption and decryption materials. 20 | 21 | ### Basic tests 22 | 23 | A positive key description for each [wrapping algorithm](../../raw-aes-keyring.md#wrapping-algorithm) MUST be generated. 24 | This MUST point to a different key for each wrapping algorithm key length in the keys manifest. 25 | The provider-id for each wrapping algorithm scheme MUST be different. 26 | A test MUST attempt to encrypt and decrypt 27 | with every available [algorithm suite](../../algorithm-suites.md#algorithm-suite-id) 28 | A test MUST attempt every [standard encryption context](./encryption-context.md#standard-encryption-contexts). 29 | -------------------------------------------------------------------------------- /framework/test-vectors/complete-vectors/raw-rsa.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Raw RSA Keyring Vectors 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Summary 11 | 12 | This describes the test cases for the [Raw RSA Keyring](../../raw-rsa-keyring.md) 13 | 14 | ## Reference-level Explanation 15 | 16 | ## Definitions 17 | 18 | - positive key description: a [key description](../key-description.md) that when parsed and generated can produce 19 | valid encryption and decryption materials. 20 | 21 | ### Basic tests 22 | 23 | A positive key descriptions for every [supported padding scheme](../../raw-rsa-keyring.md#supported-padding-schemes) MUST be generated. 24 | The provider-id for each padding scheme MUST be different. 25 | A test MUST attempt to encrypt and decrypt 26 | with every available [algorithm suite](../../algorithm-suites.md#algorithm-suite-id) 27 | A test MUST attempt every [standard encryption context](./encryption-context.md#standard-encryption-contexts). 28 | -------------------------------------------------------------------------------- /framework/test-vectors/decryption-manifest.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Decryption Manifest 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Dependencies 11 | 12 | This serves as a reference of all features that this feature depends on. 13 | 14 | | Feature | Min Version | Max Version | 15 | | ---------------------------------------- | ----------- | ----------- | 16 | | [keys-description](./key-description.md) | 1 | n/a | 17 | | [keys-manifest](./keys-manifest.md) | 1 | n/a | 18 | 19 | ## Summary 20 | 21 | The decrypt manifest describes static test vectors. 22 | This includes all the necessary details such as keyrings, cmm, encryption context, algorithm suite, etc. 23 | 24 | ## Out of Scope 25 | 26 | This file is not a description of how the test vectors that will be generated by a compatible client should be decrypted. 27 | 28 | ## Motivation 29 | 30 | We need a way of describing all scenarios that we want to cover with test vectors. 31 | This will be used for generating test vectors with an unknown implementation 32 | to be tested for compatibility using a known correct implementation. 33 | It will also help us reason about the correctness of specific features or keyrings. 34 | It can also be used to ensure known bad vectors or incorrect configuration cannot lead to successful decryption 35 | by demonstrating that different configurations succeed or fail correctly. 36 | 37 | ## Guide-level Explanation 38 | 39 | This type of manifest describes test vectors to create. 40 | Processing these test scenarios will result in [encryption materials](../structures.md#encryption-materials). 41 | 42 | Each test scenario includes all necessary instructions to construct 43 | a [decryption materials request](../cmm-interface.md#decryption-materials-request). 44 | This includes all necessary inputs including algorithm suite, encryption context, and keyrings/CMMs. 45 | 46 | ## Reference-level Explanation 47 | 48 | ### Manifest 49 | 50 | Map identifying the manifest. 51 | 52 | - `type` : Identifies the manifest as an AWS Encryption SDK message encryption manifest. 53 | - MUST be `aws-mpl-encrypt` 54 | - `version` : Identifies the version of this feature document that describes the manifest. 55 | 56 | #### Keys 57 | 58 | URI identifying a [keys manifest](./keys-manifest.md) to use with all tests. 59 | 60 | ### Tests 61 | 62 | Map object mapping a test case ID to a test case description 63 | that describes how to generate an [encryption materials request](../cmm-interface.md#encryption-materials-request). 64 | Optional members on [encryption materials request](../cmm-interface.md#encryption-materials-request) 65 | are optional in the test. 66 | 67 | - type : The type of test 68 | - Allowed Values 69 | - positive-keyring : A successful request for encrypt materials that should also result in a successful decrypt 70 | - negative-decrypt-keyring: A successful request for encrypt materials that should result in a failure to decrypt 71 | - description : A human readable decryption of what is being tested 72 | 73 | - algorithmSuiteId : Hex string of supported [Algorithm ID](../algorithm-suites.md#algorithm-suite-id) 74 | - commitmentPolicy : 75 | - encryptedDataKeys : 76 | - encryptionContext : Map of keys and values to use for encryption context 77 | - keyDescription : The [key description](./key-description.md) used in the decrypt test for this test 78 | - reproducedEncryptionContext : The reproducedEncryptionContext to use in the decrypt test for this test 79 | - errorDescription : The description of the expected encrypt error for a `negative-decrypt-keyring` test 80 | - expectedResult : A structure to store the expected result for a successful `positive-keyring` test. 81 | - plaintextDataKey : The expected plaintext data key 82 | - symmetricSigningKey : The expected symmetric signing key 83 | - requiredEncryptionContextKeys : The expected required encryption context keys 84 | 85 | ### Examples 86 | 87 | ```json 88 | 89 | ``` 90 | -------------------------------------------------------------------------------- /framework/test-vectors/esdk-test-vector-enumeration.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # ESDK Test Vector Enumeration 5 | 6 | This document performs the [test vector enumeration](test-vector-enumeration.md) process for the ESDK 7 | to construct the full suite of test vectors 8 | for the ESDK. 9 | 10 | The full suite of test vectors can be constructed 11 | by [enumerating all input configurations](test-vector-enumeration.md#enumerating-input-configurations) from this spec's input dimensions 12 | and [evaluating each configuration's expected result](test-vector-enumeration.md#determining-expected-results) from this spec's evaluation rules. 13 | 14 | ## Input dimensions 15 | 16 | - Every [MPL input dimension](mpl-test-vector-enumeration.md#input-dimensions) is an input dimension for ESDK. 17 | - plaintext: Range of [representative plaintext values](#representative-plaintext-constraints) 18 | - commitment policy: Range of allowed [commitment policies](../../client-apis/client.md#commitment-policy) 19 | - frame size: Range of [representative frame sizes](#representative-frame-sizes) 20 | - maximum encrypted data keys: Range of [representative number of maximum encrypted data keys](#representative-number-of-maximum-encrypted-data-keys-edks) 21 | 22 | ## Evaluation rules 23 | 24 | - Every [MPL evaluation rule](mpl-test-vector-enumeration.md#evaluation-rules) is an evaluation rule for ESDK. 25 | 26 | ## Representative values 27 | 28 | ### Representative frame sizes 29 | 30 | - Non-framed data: `frame size = 0` 31 | - The representative frame size value for non-framed data 32 | MUST have frame size = 0. 33 | - Small frame: `0 < frame size < 4096` 34 | - The representative value for a small frame 35 | MUST have frame size between 0 and 4096. 36 | - Default frame: `frame size = 4096` 37 | - The representative value for the default frame size 38 | MUST have frame size = 4096. 39 | - Large frame: `frame size > 4096` 40 | - The representative value for a large frame 41 | MUST have frame size greater than 4096. 42 | 43 | ### Representative plaintext constraints 44 | 45 | #### Framed data 46 | 47 | These MUST only be used if `frame size > 0`. 48 | 49 | - Empty: `length = 0` 50 | - The representative plaintext value for empty framed data 51 | MUST have length = 0. 52 | - Small: `0 < length < 10` 53 | - The representative plaintext value for small framed data 54 | MUST have length between 0 and 10. 55 | - If `frame size < 10`, omit this. 56 | - Medium: `10 ≤ length < 1000` 57 | - The representative plaintext value for medium framed data 58 | MUST have length of at least 10 and less than 1000. 59 | - If `frame size < 1000`, omit this. 60 | - Large: `1000 ≤ length <` [frame size](#representative-frame-sizes) 61 | - The representative plaintext value for large framed data 62 | MUST have length of at least 1000 and less than the configured frame size. 63 | - Largest frame: `length = frame size` 64 | - The representative plaintext value for the largest frame 65 | MUST have length equal to the configured frame size. 66 | - Largest frame + partial frame: `frame size < length < 2\*(frame size)` 67 | - The representative plaintext value for a largest frame plus partial frame 68 | MUST have length between the configured frame size 69 | and twice the configured frame size. 70 | - Two largest frames: `length = 2\*(frame size)` 71 | - The representative plaintext value for two largest frames 72 | MUST have length equal to twice the configured frame size. 73 | - Many frames: `2*(frame size) < length < (frame size)\*(maximum # of frames)` 74 | - The representative plaintext value for many frames 75 | MUST have length between twice the configured frame size 76 | and ((the configured maximum number of frames) times (the configured frame size)). 77 | - Maximum frames: `length = (frame size)\*(maximum # of frames)` 78 | - The representative plaintext value for maximum frames 79 | MUST have length equal to the configured maximum number of frames times the configured frame size. 80 | 81 | #### Non-framed data 82 | 83 | These MUST only be used if `frame length = 0`. 84 | 85 | - Empty: `length = 0` 86 | - The representative plaintext value for empty non-framed data 87 | MUST have length equal to 0. 88 | - Small: `0 < length < 10` 89 | - The representative plaintext value for small non-framed data 90 | MUST have length between 0 and 10. 91 | - Medium: `10 ≤ length < 1000` 92 | - The representative plaintext value for empty non-framed data 93 | MUST have length of at least 10 and less than 1000. 94 | - Large: `1000 < length ≤ 2^32` 95 | - The representative plaintext value for empty non-framed data 96 | MUST have length of at least 1000 and less than 2^32. 97 | 98 | ### Representative number of maximum encrypted data keys (EDKs) 99 | 100 | - No configured value 101 | - The representative value for no configured maxiumum number of EDKs 102 | MUST be some unset value 103 | that is interpreted as "no maximum value" by the ESDK implementation. 104 | - Zero: `max EDKs = 0` 105 | - The representative value for zero maximum EDKs 106 | MUST have length = 0. 107 | - One: `max EDKs = 1` 108 | - The representative value for one maximum EDK 109 | MUST have length = 1. 110 | - Few: `1 < max EDKs < 10` 111 | - The representative value for few maximum EDKs 112 | MUST have length between 1 and 10. 113 | - Many: `10 ≤ max EDKs` 114 | - The representative value for many maximum EDKs 115 | MUST have length of at least 10. 116 | -------------------------------------------------------------------------------- /framework/test-vectors/key-description.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Key Description 5 | 6 | ## Version 7 | 8 | 1.0.0 9 | 10 | ## Dependencies 11 | 12 | This serves as a reference of all features that this feature depends on. 13 | 14 | | Feature | Min Version | Max Version | 15 | | ----------------------------------- | ----------- | ----------- | 16 | | [keys-manifest](./keys-manifest.md) | 1 | n/a | 17 | 18 | ## Summary 19 | 20 | The Key Description structure defines a standard way of describing 21 | keyring configuration as part of a manifest. 22 | The MPL describes a common way 23 | to configure key distribution. 24 | These key descriptions explain how to instantiate the required [keyring](../keyring-interface.md) 25 | or [cmm](../cmm-interface.md). 26 | 27 | ## Out of Scope 28 | 29 | This file does not define any actual manifests, 30 | only a common structure that is used in Crypto Tools libraries manifest definitions 31 | that need to include a description of a key description. 32 | 33 | ## Motivation 34 | 35 | Several manifests have a requirement to define keyrings that need to 36 | be constructed while processing that manifest. 37 | In order to maintain consistency for these definitions across manifest types, 38 | this file defines how keyrings are defined in any 39 | manifest type that needs to describe keyring configuration. 40 | 41 | There are also legacy test vectors that exist. 42 | This key description MUST be compatible 43 | with these legacy objects. 44 | These objects were referred to as Master Keys 45 | and Master Key Providers. 46 | 47 | ## Guide-level Explanation 48 | 49 | The master key structure is a JSON structure that identifies necessary characteristics 50 | about an AwsCryptographicMaterialProvidersLibrary keyring. 51 | 52 | ## Reference-level Explanation 53 | 54 | ### Contents 55 | 56 | A key description structure is defined as a JSON object with the following members: 57 | 58 | - `type` : Type of keyring/cmm 59 | - Allowed Values 60 | - `static-material-keyring` 61 | - `aws-kms` 62 | - `aws-kms-mrk-aware` 63 | - `aws-kms-mrk-aware-discovery` 64 | - `raw` 65 | - `aws-kms-hierarchy` 66 | - `aws-kms-rsa` 67 | - `caching-cmm` 68 | - `required-encryption-context-cmm` 69 | - `key` : Name of key from a `keys` manifest. 70 | For some types, like discovery or CMMs, a key is not required. 71 | - The key ID should always be `key.key-id` 72 | 73 | For the `raw` type the following members exist: 74 | 75 | - `provider-id` : Key Provider ID (required for Raw keyrings) 76 | - `encryption-algorithm` : Encryption Algorithm (required for Raw keyrings) 77 | - Allowed Values 78 | - `aes` 79 | - `rsa` 80 | 81 | For a `raw` `rsa` the following members exist: 82 | 83 | - `padding-algorithm` : Padding Algorithm (required for RSA Raw Master Keys) 84 | - Allowed Values 85 | - `pkcs1` 86 | - `oaep-mgf1` 87 | - `padding-hash` : Hash Algorithm used with Padding Algorithm (required if `padding-algorithm` is `oaep-mgf1`) 88 | - Allowed Values 89 | - `sha1` 90 | - `sha256` 91 | - `sha384` 92 | - `sha512` 93 | 94 | For a `aws-kms-mrk-aware-discovery` type the following members exist: 95 | 96 | - `key` is not required. 97 | - `default-mrk-region` An AWS region 98 | - `aws-kms-discovery-filter` that has the following: 99 | - `partition` A partition string 100 | - `account-ids` An array of AWS account ID string 101 | 102 | For a CMM types like `caching-cmm` or `required-encryption-context-cmm` type 103 | an `underlying` member exists that is the keyring or cmm that this element would wrap. 104 | 105 | ### Examples 106 | 107 | ```json 108 | { 109 | "type": "aws-kms", 110 | "key": "us-west-2-decryptable" 111 | } 112 | ``` 113 | 114 | ```json 115 | { 116 | "type": "raw", 117 | "provider-id": "aws-raw-vectors-persistent", 118 | "key": "rsa-4096-private", 119 | "encryption-algorithm": "rsa", 120 | "padding-algorithm": "oaep-mgf1", 121 | "padding-hash": "sha256" 122 | } 123 | ``` 124 | 125 | ```json 126 | { 127 | "type": "aws-kms-mrk-aware-discovery", 128 | "default-mrk-region": "us-west-2", 129 | "aws-kms-discovery-filter": { 130 | "partition": "aws", 131 | "account-ids": ["658956600833"] 132 | } 133 | } 134 | ``` 135 | 136 | ```json 137 | { 138 | "type": "caching-cmm", 139 | "underlying": { 140 | "type": "static-material-keyring", 141 | "key": "static-cashable-plaintext-data-key" 142 | }, 143 | "cacheLimitTtlSeconds": 5, 144 | "getEntryIdentifier": "+m9XmK8rzu0FLMlFmaElNNLcW7Cpp452Tcb/HepBGBbMR2DEfQBRroQbS6jq1acjpjx5hQ9GRKphCCy/ltmHFw==", 145 | "putEntryIdentifier": "" 146 | } 147 | ``` 148 | -------------------------------------------------------------------------------- /framework/test-vectors/mpl-test-vector-enumeration.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # MPL Test Vector Enumeration 5 | 6 | This document performs the [test vector enumeration](test-vector-enumeration.md) process for the MPL 7 | to construct the full suite of test vectors 8 | for the MPL. 9 | 10 | The full suite of test vectors can be constructed 11 | by [enumerating all input configurations](test-vector-enumeration.md#enumerating-input-configurations) from this spec's input dimensions 12 | and [evaluating each configuration's expected result](test-vector-enumeration.md#determining-expected-results) from this spec's evaluation rules. 13 | 14 | ## Input dimensions 15 | 16 | This section enumerates the [input dimensions](../test-vectors/test-vector-enumeration.md#input-dimensions) 17 | for MPL test vectors: 18 | 19 | - algorithm suite ID: Range of supported [Algorithm IDs](../algorithm-suites.md#algorithm-suite-id) 20 | - encryption context: Range of [representative encryption context values](./complete-vectors/encryption-context.md) 21 | - required encryption context keys: Range of every [representative required encryption context key](#representative-required-encryption-context-keys) 22 | - reproduced encryption context: Range is every [representative reproduced encryption context](#representative-reproduced-encryption-context) 23 | - encrypt key description: Range of all [key descriptions](./key-description.md) used to request encrypt materials 24 | - decrypt key description: Range of all [key descriptions](./key-description.md) used to decrypt 25 | -------------------------------------------------------------------------------- /proposals/2022-10-27_rsa-keyring-v2/proposal.md: -------------------------------------------------------------------------------- 1 | [//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." 2 | [//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" 3 | 4 | # Raw RSA Keyring V2 5 | 6 | ## Affected Features 7 | 8 | This serves as a reference of all features that this change affects. 9 | 10 | | Feature | 11 | | ----------------------------------------------------- | 12 | | [Raw RSA Keyring](../../framework/raw-rsa-keyring.md) | 13 | 14 | ## Affected Specifications 15 | 16 | This serves as a reference of all specification documents that this change affects. 17 | 18 | | Specification | 19 | | -------------------------------------------------------------- | 20 | | [Raw RSA Keyring](../../framework/aws-kms/aws-kms-rsa-keyring) | 21 | 22 | ## Definitions 23 | 24 | ### Conventions used in this document 25 | 26 | The key words 27 | "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 28 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 29 | in this document are to be interpreted as described in 30 | [RFC 2119](https://tools.ietf.org/html/rfc2119). 31 | 32 | ## Summary 33 | 34 | The ESDK message format includes a digital signature over all of body of the message. 35 | This signature is verified on decrypt with a verification key that is 36 | persisted in the Encryption Context. 37 | With an AWS KMS Keyring 38 | the Encryption Context is included in the 39 | Encrypt and Decrypt invocations as encryption context. 40 | This encryption context is immutable 41 | because it is enforce by AWS KMS 42 | and it is bound to the encrypted data key. 43 | 44 | But RSA is not an Authenticated Encryption with Additional Data (AEAD) cipher; 45 | as such, it's invocation cannot include encryption context. 46 | This means that an by default an AWS KMS RSA keyring 47 | would not have these properties. 48 | 49 | To solve this, 50 | we propose storing a representation of the Encryption Context in 51 | the Encrypted Data Key's ciphertext of AWS KMS RSA Keyrings. 52 | 53 | On Decrypt, 54 | this representation would be compared to the given Encryption Context. 55 | If this comparison fails, the decrypt would fail. 56 | 57 | ## Out of Scope 58 | 59 | This proposal does not address: 60 | 61 | - Integrating the Raw RSA Keyring 62 | 63 | ## Motivation 64 | 65 | Digital Signatures are a prominent feature of the ESDK's message format. 66 | It is a miss that Verification Key is not protected in the RSA Keyring. 67 | These changes make the Encryption Context bound to the encrypted data key 68 | and the message more tightly bound together. 69 | -------------------------------------------------------------------------------- /util/extract.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | /* This is some sugar to produce compliance TOML 6 | * from existing markdown. 7 | * It uses `cargo-compliance`, `xml2rfc` and `kramdown`. 8 | * 9 | */ 10 | 11 | const { extname, basename, resolve, dirname, join, relative } = require("path"); 12 | const { execSync } = require("child_process"); 13 | const { 14 | readFileSync, 15 | writeFileSync, 16 | statSync, 17 | constants, 18 | mkdirSync, 19 | } = require("fs"); 20 | const ext = ".md"; 21 | const pathToComplianceRoot = `${relative(process.cwd(), `${__dirname}/../compliance`)}`; 22 | 23 | needs( 24 | () => execSync("which kramdown-rfc2629"), 25 | "kramdown-rfc2629 needs to be installed, try `gem install kramdown-rfc2629 -v 1.5.21`" 26 | ); 27 | needs( 28 | () => execSync("which xml2rfc"), 29 | "xml2rfc needs to be installed, try `pip install xml2rfc==3.5.0`" 30 | ); 31 | needs( 32 | () => execSync("which duvet"), 33 | "duvet needs to be installed, try `util/install-duvet`" 34 | ); 35 | 36 | /* May need to change this to a better parser... 37 | * When run with a shebang 38 | * the argv list will start, 39 | * with the path to node 40 | * then the path to this script. 41 | * So the 3rd element ([2]) 42 | * is the first user parameter. 43 | */ 44 | process.argv.slice(2).map(extract_needs).map(extract); 45 | 46 | function extract(filePath) { 47 | const fileName = basename(filePath, ext); 48 | const tmpdir = require("os").tmpdir(); 49 | const markdownSpecFile = resolve(tmpdir, `${fileName}${ext}`); 50 | const xmlRfcFile = resolve(tmpdir, `${fileName}.xml`); 51 | const complianceSpec = join(pathToComplianceRoot, dirname(filePath), `${fileName}.txt`); 52 | const complianceDir = join(pathToComplianceRoot, dirname(filePath), fileName); 53 | 54 | // Create the root compliance directory if it doesn't exist 55 | try { 56 | statSync(pathToComplianceRoot).isDirectory(); 57 | } catch (ex) { 58 | mkdirSync(pathToComplianceRoot, { recursive: true }); 59 | } 60 | 61 | /* 62 | 1. Get the file name without extension 63 | 2. Add the RFC crap to a new tmp file 64 | 3. kramdown 65 | 4. xml2rfc 66 | 5. cargo-compliance extract 67 | */ 68 | 69 | // Write the spec file with the header and footer 70 | writeFileSync( 71 | markdownSpecFile, 72 | [header(fileName), readFileSync(filePath, { encoding: "utf8" }), footer()].join("\n"), 73 | { encoding: "utf8" } 74 | ); 75 | 76 | // Convert the markdown file from RFC XML 77 | execSync(["kramdown-rfc2629", "-3", markdownSpecFile, ">", xmlRfcFile].join(" "), {stdio: 'inherit'}); 78 | 79 | // An existing spec may exists, clean up first 80 | try { 81 | // This will throw if the directory does not exist 82 | statSync(complianceDir).isDirectory(); 83 | // If the directory exists, remove it. Nothing could go wrong... :( 84 | execSync(["rm", "-rf", complianceDir].join(" ")); 85 | } catch (ex) { 86 | // If the directory does not exist, that is OK 87 | needs(ex.errno === -2, "Unknown error"); 88 | } 89 | 90 | // make sure the compliance directory exists 91 | mkdirSync(complianceDir, { recursive: true }); 92 | 93 | // Convert the RFC XML to a ietf rfc 94 | execSync(["xml2rfc", 95 | "-P", xmlRfcFile, 96 | "-s", "'Too long line found'", // Suppress warnings about long table line length 97 | "-s", "'Total table width'", // Suppress warnings about overall table width 98 | "-o", complianceSpec 99 | ].join(" "), {stdio: 'inherit'}); 100 | 101 | const args = ["duvet", "extract", `${complianceSpec}`, "-o", "compliance"]; 102 | // extract the specification 103 | execSync(args.join(" "), { encoding: 'utf8', stdio: 'inherit'}); 104 | } 105 | 106 | function extract_needs(filePath) { 107 | needs(extname(filePath) === ext, `Unsupported ext ${ext}`); 108 | needs( 109 | () => statSync(filePath).isFile(), 110 | `Specification file ${filePath} does not exist.` 111 | ); 112 | return filePath; 113 | } 114 | 115 | // The `ipr: none` is particularly important 116 | // this removed boilerplate (especially Copyright) 117 | function header(docName) { 118 | return `--- 119 | title: ${docName} 120 | abbrev: ${docName} 121 | docname: ${docName} 122 | category: info 123 | ipr: none 124 | area: General 125 | workgroup: AWS Crypto Tools 126 | keyword: INTERNAL-ONLY 127 | stand_alone: yes 128 | pi: [toc, sortrefs, symrefs] 129 | author: 130 | - 131 | ins: Amazon AWS 132 | name: Amazon AWS 133 | organization: Amazon AWS 134 | email: cryptools+rfc@amazon.com 135 | normative: 136 | RFC2119: 137 | informative: 138 | --- abstract 139 | The ${docName} specification for the AWS Encryption SDK. 140 | --- middle 141 | # Conventions and Definitions 142 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", 143 | "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this 144 | document are to be interpreted as described in BCP 14 {{RFC2119}} {{!RFC8174}} 145 | when, and only when, they appear in all capitals, as shown here 146 | `; 147 | } 148 | 149 | function footer() { 150 | return `--- back 151 | # Acknowledgments 152 | {:numbered="false"} 153 | `; 154 | } 155 | 156 | function needs(condition, errorMessage) { 157 | if (typeof condition === "function") { 158 | try { 159 | needs(condition(), errorMessage); 160 | } catch (ex) { 161 | throw new Error(errorMessage); 162 | } 163 | } 164 | 165 | if (!condition) { 166 | throw new Error(errorMessage); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /util/install-duvet: -------------------------------------------------------------------------------- 1 | #/usr/bin/env bash 2 | # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 3 | # SPDX-License-Identifier: Apache-2.0 4 | 5 | set -e 6 | 7 | # Make sure that rustup in installed 8 | if ! command -v rustup &> /dev/null; then 9 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 10 | fi 11 | 12 | # 13 | if ! command -v cargo &> /dev/null; then 14 | rustup install stable 15 | fi 16 | 17 | DIR=$(mktemp -d) 18 | git clone git@github.com:awslabs/duvet.git $DIR 19 | cargo +stable install --force --path $DIR/ 20 | 21 | if !command -v duvet &> /dev/null; then 22 | echo 'Add `~/.cargo/bin` to your $PATH' 23 | fi 24 | -------------------------------------------------------------------------------- /util/report.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { relative, join, extname } = require("path"); 4 | const { execSync } = require("child_process"); 5 | 6 | needs( 7 | () => execSync("which duvet"), 8 | "duvet needs to be installed try `util/install-duvet`" 9 | ); 10 | 11 | const data = execSync("git remote -v") 12 | .toString() 13 | .split("\n") 14 | /* Push because that is where the code can go */ 15 | .filter((line) => line.includes("(fetch)")) 16 | /* Trim the identifier by removing the name and the (push) */ 17 | .map((line) => line.split(/\s/)[1]) 18 | /* Only git or https please */ 19 | .filter((line) => line.startsWith("https://") || line.startsWith("git@github.com:")) 20 | /* Convert git to https urls */ 21 | .map((line) => 22 | line.startsWith("https://") 23 | ? line 24 | : line.replace("git@github.com:", "https://github.com/") 25 | ) 26 | /* Drop the `.git` because this is not in GitHub blob or issue urls */ 27 | .map((line) => line.replace(".git", "")) 28 | /* aws or awslabs only, no forks */ 29 | .filter((line) => line.startsWith("https://github.com/aws")); 30 | 31 | needs(data.length, "Not in a git sandbox?"); 32 | needs(data.length === 1, `Ambiguous urls ${JSON.stringify(data)}`); 33 | const gitHubUrl = new Set(data).values().next().value; 34 | 35 | /* cargo-compliance need to have all the specification paths line up. 36 | * The extracted paths are relative to the specification repo, 37 | * but when running the report the specification repo is a sub-module. 38 | * To make this work, I run cargo-compliance in the specification repo, 39 | * but then output to the this command was run 40 | * (the root of the implementation repo). 41 | * A little work also needs to be done on the source files as well. 42 | */ 43 | const specificationDirectory = relative(process.cwd(), `${__dirname}/..`); 44 | const relativePath = relative(specificationDirectory, process.cwd()); 45 | 46 | /* May need to change this to a better parser... 47 | * When run with a shebang 48 | * the argv list will start, 49 | * with the path to node 50 | * then the path to this script. 51 | * So the 3rd element ([2]) 52 | * is the first user parameter. 53 | */ 54 | const sourcePatterns = process.argv 55 | .slice(2) 56 | // Only support relative paths 57 | .map((pattern) => join(relativePath, relative(process.cwd(), pattern))) 58 | /* Python files use # for comments 59 | * Therefore //= and //# can not work 60 | * to identify the compliance sections. 61 | * The compliance tool lets you override 62 | * the meta and content patterns. 63 | * So lets make it easy for Python. 64 | */ 65 | .map((pattern) => (extname(pattern) === ".py" ? `(# //=,# //#)${pattern}` : pattern)) 66 | .map((pattern) => `--source-pattern '${pattern}'`); 67 | needs(sourcePatterns.length, "No source patterns"); 68 | 69 | const args = [ 70 | "duvet", 71 | "report ", 72 | "--ci", 73 | `--spec-pattern "compliance/**/*.toml" `, 74 | ...sourcePatterns, 75 | "--require-citations true ", 76 | "--require-tests true ", 77 | `--blob-link "${gitHubUrl}/blob/$BLOB" `, 78 | `--issue-link "${gitHubUrl}/issues" `, 79 | "--no-cargo ", 80 | `--html ${join(relativePath, "specification_compliance_report.html")}`, 81 | ]; 82 | 83 | try { 84 | const out = execSync(args.join(" "), { 85 | encoding: "utf8", 86 | cwd: specificationDirectory, 87 | }); 88 | console.log(out); 89 | } catch (ex) { 90 | const { stdout, status } = ex; 91 | if (stdout) console.log(stdout); 92 | process.exit(status); 93 | } 94 | 95 | function needs(condition, errorMessage) { 96 | if (!condition) { 97 | throw new Error(errorMessage); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /util/specification_extract.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT_SOURCE=$(dirname "$0") 4 | 5 | FILES=("$SCRIPT_SOURCE"/../framework/**/*.md) 6 | FILES+=("$SCRIPT_SOURCE"/../framework/*.md) 7 | FILES+=("$SCRIPT_SOURCE"/../client-apis/*.md) 8 | FILES+=("$SCRIPT_SOURCE"/../data-format/*.md) 9 | 10 | echo "Extracting ${#FILES[@]} files:" 11 | 12 | for FILE in "${FILES[@]}" 13 | do 14 | RESOLVED="$(cd "$(dirname "$FILE")"; pwd -P)/$(basename "$FILE")" 15 | echo "Extracting: $RESOLVED" 16 | "$SCRIPT_SOURCE"/extract.js "$FILE" 17 | done 18 | --------------------------------------------------------------------------------