Skip to content

Commit 31b0534

Browse files
lavaleriseebeesmattsb42-aws
authored
doc: add change doc to specify max plaintext length input on encrypt (#138)
* doc: add change doc to specify max plaintext length input on encrypt * make pretty * Fix typos and update summary * make pretty again * Update changes/2020-06-17_encrypt-max-plaintext-length-input/change.md Co-authored-by: seebees <[email protected]> * Relax API restrictions, scope requirements to Encrypt operation * Apply suggestions from code review Co-authored-by: seebees <[email protected]> * Apply changes to specification * Apply suggestions from code review Co-authored-by: seebees <[email protected]> * Update changes/2020-06-17_encrypt-max-plaintext-length-input/change.md Co-authored-by: Matt Bullock <[email protected]> * PR feedback * Fix typo Co-authored-by: seebees <[email protected]> Co-authored-by: Matt Bullock <[email protected]>
1 parent 623992d commit 31b0534

File tree

3 files changed

+234
-6
lines changed

3 files changed

+234
-6
lines changed
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
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.

client-apis/encrypt.md

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,21 @@ The following inputs to this behavior are REQUIRED:
4141
- [Plaintext](#plaintext)
4242
- either a [Cryptographic Materials Manager (CMM)](../framework/cmm-interface.md) or a [Keyring](../framework/keyring-interface.md)
4343

44-
The following as inputs to this behavior are OPTIONAL:
44+
The following inputs to this behavior are OPTIONAL:
4545

4646
- [Algorithm Suite](#algorithm-suite)
4747
- [Encryption Context](#encryption-context)
4848
- [Frame Length](#frame-length)
49-
- [Plaintext Length](#plaintext-length)
49+
50+
If the input [plaintext](#plaintext) is of unknown length, the caller MAY also input a
51+
[Plaintext Length Bound](#plaintext-length-bound).
52+
53+
Implementations SHOULD ensure that a caller is not able to specify both a [plaintext](#plaintext)
54+
with known length and a [Plaintext Length Bound](#plaintext-length-bound) by construction.
55+
If a caller is able to specify both an input [plaintext](#plaintext) with known length and
56+
a [Plaintext Length Bound](#plaintext-length-bound),
57+
[Plaintext Length Bound](#plaintext-length-bound) MUST NOT be used during the Encrypt operation
58+
and MUST be ignored.
5059

5160
### Plaintext
5261

@@ -75,9 +84,12 @@ The [algorithm suite](#algorithm-suite.md) that SHOULD be used for encryption.
7584
The [frame length](../data-format/message-header.md#frame-length) to use for [framed data](../data-format/message-body.md).
7685
This value MUST NOT exceed the value 2^32 - 1.
7786

78-
### Plaintext Length
87+
### Plaintext Length Bound
88+
89+
A bound on the length of [plaintext](#plaintext) with an unknown length to encrypt.
7990

80-
A bound on the length of the [plaintext](#plaintext) to encrypt.
91+
If this input is provided, this operation MUST NOT encrypt a plaintext with length
92+
greater than this value.
8193

8294
## Output
8395

@@ -99,6 +111,11 @@ MUST be constructed as follows:
99111
Otherwise, this is an empty encryption context.
100112
- Algorithm Suite: If provided, this is the [input algorithm suite](#algorithm-suite).
101113
Otherwise, this field is not included.
114+
- Max Plaintext Length: If the [input plaintext](#plaintext) has known length,
115+
this length MUST be used.
116+
If the input [plaintext](#plaintext) has unknown length and a [Plaintext Length Bound](#plaintext-length-bound)
117+
was provided, this is the [Plaintext Length Bound](#plaintext-length-bound).
118+
Otherwise, this field is not included.
102119

103120
The [algorithm suite](../framework/algorithm-suites.md) used in all aspects of this behavior MUST be the algorithm suite in the
104121
[encryption materials](../framework/structures.md#encryption-materials) returned from the [Get Encryption Materials](../framework/cmm-interface.md#get-encryption-materials) call.
@@ -153,6 +170,10 @@ Each frame of the [message body](../data-format/message-body.md) is serialized w
153170
- The plaintext contains part of the input [plaintext](#plaintext) this frame is encrypting.
154171
- [Authentication Tag](../data-format/message-body.md#authentication-tag): MUST be the authentication tag outputted by the above encryption.
155172

173+
If [Plaintext Length Bound](#plaintext-length-bound) was specified on input
174+
and this operation determines that the plaintext being encrypted has a length greater than this value,
175+
this operation MUST immediately fail.
176+
156177
If the [algorithm suite](../framework/algorithm-suites.md) contains a [signature algorithm](../framework/algorithm-suites.md#signature-algorithm),
157178
the output [message](../data-format/message.md) MUST contain a [message footer](../data-format/message-footer.md).
158179
The footer is serialized with the following specifics:

framework/cmm-interface.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,10 @@ The encryption materials request MUST include the following:
6868
The encryption request MAY include the following:
6969

7070
- [Algorithm Suite](algorithm-suites.md)
71-
- [Plaintext Length](../client-apis/encrypt.md#plaintext-length)
72-
- The length of the plaintext to be encrypted MUST not be larger than this value.
71+
- Max Plaintext Length
72+
- This value represent the maximum length of the plaintext to be encrypted
73+
using the returned materials.
74+
The length of the plaintext to be encrypted MUST not be larger than this value.
7375

7476
#### Decrypt Materials Request
7577

0 commit comments

Comments
 (0)