|
| 1 | +[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." |
| 2 | +[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" |
| 3 | + |
| 4 | +# Encrypt Max Plaintext Length Input |
| 5 | + |
| 6 | +## Affected Features |
| 7 | + |
| 8 | +| Feature | |
| 9 | +| ------------------------------------------------- | |
| 10 | +| [Encrypt](../../client-apis/encrypt.md) | |
| 11 | +| [CMM Interface](../../framework/cmm-interface.md) | |
| 12 | + |
| 13 | +## Affected Specifications |
| 14 | + |
| 15 | +| Specification | |
| 16 | +| ------------------------------------------------- | |
| 17 | +| [Encrypt](../../client-apis/encrypt.md) | |
| 18 | +| [CMM Interface](../../framework/cmm-interface.md) | |
| 19 | + |
| 20 | +## Affected Implementations |
| 21 | + |
| 22 | +| Language | Repository | |
| 23 | +| -------- | ----------------------------------------------------------------------------- | |
| 24 | +| Python | [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python) | |
| 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 | +### Known-Length Plaintext |
| 37 | + |
| 38 | +Any plaintext input to the Encrypt operation where the total length of that plaintext |
| 39 | +can be immediately determined. |
| 40 | +For example, if a customer supplies plaintext as a string or byte array to Encrypt, |
| 41 | +that is a known-length plaintext. |
| 42 | + |
| 43 | +### Unknown-Length Plaintext |
| 44 | + |
| 45 | +Any plaintext input to the Encrypt operation where the total length of that plaintext |
| 46 | +cannot be immediately determined. |
| 47 | +For example, if a customer supplies plaintext as a stream to Encrypt, |
| 48 | +that is a unknown-length plaintext. |
| 49 | + |
| 50 | +## Summary |
| 51 | + |
| 52 | +The Encrypt operation interacts with plaintext that can either have a known length or an |
| 53 | +unknown length. |
| 54 | +If the input plaintext is a unknown-length plaintext, |
| 55 | +the Encrypt operation MUST also take an optional input that bounds the length of that input. |
| 56 | + |
| 57 | +The specification already specifies a |
| 58 | +[plaintext length](https://github.com/awslabs/aws-encryption-sdk-specification/blob/be6870b2513f4ca44bea8f2e0b5eb4808dba4365/client-apis/encrypt.md#plaintext) |
| 59 | +input on the Encrypt operation that describes a bound on the plaintext length, |
| 60 | +however its effect on the Encrypt operation's behavior is unspecified. |
| 61 | + |
| 62 | +This change renames this input to `plaintext length bound` in the specification |
| 63 | +to be a more accurate reflection of its behavior and intent, |
| 64 | +and specifies the correct behavior during the Encrypt operation. |
| 65 | +Specifically, in the scope of the Encrypt operation its value MUST be passed to the CMM. |
| 66 | + |
| 67 | +Additionally, it is unclear in the spec what the behavior should be |
| 68 | +if the input plaintext has a known-length |
| 69 | +and the customer specifies a bound on the length of that plaintext. |
| 70 | + |
| 71 | +This change proposes that in the scope of the Encrypt operation, |
| 72 | +an input plaintext is either of known length, |
| 73 | +of unknown length with customer supplied estimated size, |
| 74 | +or unknown length with no customer supplied estimated size. |
| 75 | +The Encrypt operation should not allow a `plaintext length bound` alongside |
| 76 | +a known-length plaintext. |
| 77 | + |
| 78 | +How a customer should express on the API level the intent to encrypt a known-length plaintext |
| 79 | +or unknown-length plaintext with or without a bound on the length |
| 80 | +depends on the specific implementation |
| 81 | +and the idioms of that implementation's language to describe APIs. |
| 82 | + |
| 83 | +## Out of Scope |
| 84 | + |
| 85 | +- Significantly changing the shape of any of our Encrypt API implementations is out of scope. |
| 86 | + |
| 87 | +## Motivation |
| 88 | + |
| 89 | +All implementations allow customers to specify a plaintext length when calling Encrypt with a |
| 90 | +unknown-length plaintext. |
| 91 | +However, its behavior in the Encrypt operation is not clearly specified. |
| 92 | + |
| 93 | +Additionally, some implementations also allow a plaintext length to be specified on Encrypt with a |
| 94 | +known-length plaintext. |
| 95 | +The behavior of Encrypt in this case is not consistent between implementations. |
| 96 | + |
| 97 | +The purpose of this change is to specify exactly how this input affects the Encrypt operation. |
| 98 | + |
| 99 | +This change renames this input to `plaintext length bound` within the spec because |
| 100 | +the intention behind the value of this input is that |
| 101 | +it is a max bound of the plaintext length, |
| 102 | +set by the customer when streaming encryption. |
| 103 | +If the actual plaintext length is greater than this value, |
| 104 | +something is wrong and the operation MUST fail. |
| 105 | +Otherwise, the Encrypt operation MUST pass this value to the CMM. |
| 106 | + |
| 107 | +The intention of this value is not to be a one to one passthrough value to the CMM. |
| 108 | +If that were the case, |
| 109 | +then we would be concerned with always letting customers specify this value for known-length plaintexts, |
| 110 | +or with possibly letting customers pass in a "unknown length" intent. |
| 111 | +We do not want to support these cases. |
| 112 | +Customers SHOULD NOT set a `max plaintext length` value for known-length plaintexts |
| 113 | +with the intention of changing CMM behavior. |
| 114 | +Instead, customers SHOULD specify this value for unknown-length plaintexts in order to use CMMs |
| 115 | +that depend on plaintext length for their internal logic. |
| 116 | + |
| 117 | +This change additionally renames the `plaintext length` field on GetEncryptionMaterialsRequest to |
| 118 | +`max plaintext length` because that better explains the intent behind this field. |
| 119 | +This field describes the max size of the plaintext that will be encrypted using the materials |
| 120 | +the CMM is to generate. |
| 121 | +This is the current state of the behavior, so the specification should describe it as such. |
| 122 | +This is renamed to a different name than `plaintext length bound` in order to |
| 123 | +distinguish the two controls. |
| 124 | + |
| 125 | +This change does not strictly prescribe how customers should express intent for the plaintext |
| 126 | +and a possible `plaintext length bound` through an API. |
| 127 | +How an API should be designed with these controls in mind depends greatly on the capabilities and |
| 128 | +idioms of the language in use. |
| 129 | +Specifically, this gets tricky for languages where the idiom is to |
| 130 | +accept an object that represents a set of customer supplied params. |
| 131 | +If a customer supplies both a known-length plaintext and a `max plaintext length`, |
| 132 | +what should be done? |
| 133 | +It doesn't make sense to have to check for bad values in the customer supplied params, |
| 134 | +given its unstructured nature. |
| 135 | +Thus, our specification recommends that languages SHOULD ensure that `max plaintext length` |
| 136 | +isn't supplied with a known-length plaintext by construction. |
| 137 | +If it doesn't, then it MUST ignore any customer supplied `max plaintext length` in the case that |
| 138 | +a known-length plaintext is supplied. |
| 139 | + |
| 140 | +## Drawbacks |
| 141 | + |
| 142 | +This change does not prescribe the name of this input in implementations, |
| 143 | +and thus there will not be a standardized name or way of specifying this input across implementations. |
| 144 | +This is because this control already exists in implementations under different names, |
| 145 | +and it is not worth breaking customer facing APIs to rename this input |
| 146 | +without significantly changing this input to benefit the customer. |
| 147 | + |
| 148 | +## Security Implications |
| 149 | + |
| 150 | +This change SHOULD NOT have any security implications. |
| 151 | + |
| 152 | +## Operational Implications |
| 153 | + |
| 154 | +This change will break any Python customer that depends on the source_length being sent to the |
| 155 | +CMM instead of the true length of a known-length plaintext. |
| 156 | + |
| 157 | +## Guide-level Explanation |
| 158 | + |
| 159 | +We need to update the spec to make the purpose and behavior of the `plaintext length` input clear |
| 160 | +by renaming it and specifying its exact behavior within the Encrypt operation: |
| 161 | + |
| 162 | +When performing the Encrypt operation on an unknown-length plaintext, |
| 163 | +customers MUST be able to specify an optional parameter `plaintext length bound`. |
| 164 | +The value of this field represents the max length of the plaintext to be encrypted. |
| 165 | +The ESDK MUST NOT encrypt a plaintext greater than this length. |
| 166 | +If it is determined during encryption that the actual plaintext length |
| 167 | +is greater than what the customer supplied on input |
| 168 | +the ESDK MUST fail. |
| 169 | +The actual name of this input, and how the customer specifies this value for the Encrypt operation |
| 170 | +MAY be different per implementation. |
| 171 | + |
| 172 | +When performing the Encrypt operation on a known-length plaintext, |
| 173 | +customers SHOULD NOT be able to specify a `plaintext length bound`. |
| 174 | +If the Encrypt operation is performing on a known-length plaintext, |
| 175 | +any such `plaintext length bound` value MUST be ignored. |
| 176 | + |
| 177 | +We also need to specify the exact behavior for how this input is used in the CMM's GetEncryptionMaterials call: |
| 178 | + |
| 179 | +- If this is a known-length plaintext, |
| 180 | + the Encrypt operation MUST pass the real plaintext length as |
| 181 | + `max plaintext length` in the CMM GetEncryptionMaterials call. |
| 182 | +- If the length of the plaintext is not known and `max plaintext length` was supplied on input, |
| 183 | + the Encrypt operation MUST pass the supplied `max plaintext length` |
| 184 | + to the CMM GetEncryptionMaterials call. |
| 185 | +- If the length of the plaintext is not known and `max plaintext length` was not supplied on input, |
| 186 | + the Encrypt operation MUST NOT specify a `max plaintext length` |
| 187 | + in the CMM GetEncryptionMaterials call. |
| 188 | + |
| 189 | +Similarly, we should rename the `plaintext length` field in the `GetEncryptionMaterialsRequest` |
| 190 | +to `max plaintext length` to clarify its intent. |
| 191 | + |
| 192 | +The CMM interface's GetEncryptionMaterialsRequest MUST contain an OPTIONAL field `max plaintext length` |
| 193 | +that represents the maximum size of the plaintext that will be encrypted using these materials. |
| 194 | +The actual name of this field MAY be different per implementation. |
| 195 | + |
| 196 | +Finally, we should specify the following for implementations of APIs that do the Encrypt operation: |
| 197 | + |
| 198 | +- Implementations SHOULD ensure that a customer is not able to specify both a known-length plaintext |
| 199 | + and a `plaintext length bound` by construction. |
| 200 | +- If a customer is able to specify both a known-length plaintext and a `plaintext length bound`, |
| 201 | + `plaintext length bound` MUST NOT be used during the Encrypt operation and MUST be ignored. |
| 202 | + |
| 203 | +## Reference-level Explanation |
| 204 | + |
| 205 | +See [Guide-level Explanation](#guide-level-explanation) above. |
0 commit comments