Skip to content

feat(test-vectors): Test vector enumeration framework #266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
May 10, 2024
Merged
2 changes: 1 addition & 1 deletion framework/test-vectors/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ looking at how test vectors are created helps reason about the edge cases of a c
## Drawbacks

Not every configuration can be practically tested.
But we can expand on the test cases.
See [test vector enumeration](test-vector-enumeration.md#selecting-a-representative-input-value) for details.

We will need to write minimal clients in every language with which we want to use these test
vectors to understand the manifests described in subsequent features.
Expand Down
17 changes: 10 additions & 7 deletions framework/test-vectors/complete-vectors/encryption-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ This is a description of the standard encryption contexts to test.

## Reference-level Explanation

### Standard Encryption Contexts

MUST have an empty map.
MUST have a small map.
MUST have a large map.
MUST have multibyte UTF8 characters in both the key and value.
MUST have multibyte non-BMP characters in both the key and value.
### Standard Encryption Contexts Constraints

- MUST have an empty map.
- The number of the items in the empty map MUST equal 0.
- MUST have a small map.
- The number of the items in the small map MUST be between 1 and 10.
- MUST have a large map.
- The number of the items in the large map MUST be greater than 10.
- MUST have multibyte UTF8 characters in both the key and value.
- MUST have multibyte non-BMP characters in both the key and value.
56 changes: 56 additions & 0 deletions framework/test-vectors/complete-vectors/hierarchy.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,59 @@ with every available [algorithm suite](../../algorithm-suites.md#algorithm-suite

For every available algorithm suite and static branch key,
a test MUST attempt to encrypt and decrypt with every [standard encryption context](./encryption-context.md#standard-encryption-contexts).

### Input dimensions

#### Encrypt

- key description
- key: range of [representative branch keys](#representative-branch-keys)

#### Decrypt

- key description
- key: range of [representative branch keys](#representative-branch-keys)
- logicalKeyStore:
- "Default",
- Represents the logical key store name on encrypt
- "Other"
- Represents any other logical key store name

### Representative branch keys

- `"static-branch-key-1"`
- MUST be some valid branch key.
- `"static-branch-key-2"`
- MUST be some valid branch key other than `static-branch-key-1`.
- `"branch-key-no-permissions"`
- MUST be some valid branch key where the test vector runner does not have permissions for the KMS key.
- `"branch-key-not-in-table"`
- MUST be some branch key ID not present in the keystore table.,
- `"branch-key-no-version"`
- MUST be some branch key that is in the table, but the configured version is not in the table.
- `"invalid-branch-key-material"`
- MUST be some branch key with illegally mutated invalid branch key material.

### Evaluation rules

- If encrypting key type is anything other than `"aws-kms-hierarchy"`
and decrypting key type is `"aws-kms-hierarchy"`,
the result MUST be `"negative-decrypt"`.
- If encrypting key type is `"aws-kms-hierarchy"`
and decrypting key type is anything other than `"aws-kms-hierarchy"`,
the result MUST be `"negative-decrypt"`.
- If the logical key store is "Other",
the result MUST be `"negative-decrypt"`.
- If `"key"` is different on encrypt and decrypt,
the result MUST be `"negative-decrypt"`.
(i.e. no key specified here is interoperable with any other key.)
- If `"key"` is any of:
- `"branch-key-no-permissions"`
- `"branch-key-not-in-table"`
- `"branch-key-no-version"`
- `"invalid-branch-key"`
(i.e. an "invalid" key with a particular invalid condition)
on either encrypt or decrypt,
the result MUST be either `"negative-encrypt"` or `"negative-decrypt"`,
depending on whether the invalid key was specified on encrypt or decrypt.
- In all other cases, the result MUST be `"positive"`.
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,55 @@ For example:

- Given the encryption context `{a:a, b:b}` with the `requiredEncryptionContextKeys`
set to `{a}`, the only success case for a message to successfully decrypt will be
to supply the reproducedEncryptionContext `{a}`.
to supply the reproducedEncryptionContext `{a:a}`.

## Input dimensions and ranges

### Encrypt

- cmm: Adds a `"RequiredEncryptionContext"` allowed value
- MUST add a `"RequiredEncryptionContext"` value to the `"cmm"` input dimension.
- required encryption context keys: Range is every [representative required encryption context key](#representative-required-encryption-context-keys)
- MUST test the full range of representative required encryption context keys.
- reproduced encryption context: Range is every [representative reproduced encryption context](#representative-reproduced-encryption-context)
- MUST test the full range of representative reproduced encryption context.

### Decrypt

These are the same as [Encrypt](#encrypt), but are specified separately so Duvet can link to unique lines for decrypt configuration.

- cmm: Adds a `"RequiredEncryptionContext"` allowed value
- MUST add a `"RequiredEncryptionContext"` value to the `"cmm"` input dimension.
- required encryption context keys: Range is every [representative required encryption context key](#representative-required-encryption-context-keys)
- MUST test the full range of representative required encryption context keys.
- reproduced encryption context: Range is every [representative reproduced encryption context](#representative-reproduced-encryption-context)
- MUST test the full range of representative reproduced encryption context.

### Representative values

#### Representative required encryption context keys

- Every subset of keys in the provided [encryption context](../../structures.md#encryption-context)
- MUST test every subset of keys in the provided encryption context.
- Any key NOT in the provided encryption context.
- MUST test with some additional key that is not in the provided encryption context.

#### Representative reproduced encryption context

- Every subset of items in the provided [encryption context](../../structures.md#encryption-context)
- MUST test every subset of items in the provided encryption context.
- Any item NOT in the provided encryption context.
- MUST test with some additional item that is not in the provided encryption context.

## Test vector evaluation rules

- If any of the `requiredEncryptionContextKeys` do not exist in the
supplied encryption context on encrypt
then the test result MUST be `negative-encrypt-keyring`. [source](#required-encryption-context-cmm-failures-on-encrypt)
- If the set of keys in `reproducedEncryptionContext` on decrypt
does not match the set of `requiredEncryptionContextKeys`,
then the test result MUST be `negative-decrypt-keyring`. [source]
- If the the value for any key in `reproducedEncryptionContext` on decrypt
does not match the value provided for that key on encrypt,
then the test result MUST be `negative-decrypt-keyring`. [source](#required-encryption-context-cmm-failures-on-decrypt)
- In all other cases, the test result MUST be `positive-keyring`.
115 changes: 115 additions & 0 deletions framework/test-vectors/esdk-test-vector-enumeration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved."
[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0"

# ESDK Test Vector Enumeration

This document performs the [test vector enumeration](test-vector-enumeration.md) process for the ESDK
to construct the full suite of test vectors
for the ESDK.

The full suite of test vectors can be constructed
by [enumerating all input configurations](test-vector-enumeration.md#enumerating-input-configurations) from this spec's input dimensions
and [evaluating each configuration's expected result](test-vector-enumeration.md#determining-expected-results) from this spec's evaluation rules.

## Input dimensions

- Every [MPL input dimension](mpl-test-vector-enumeration.md#input-dimensions) is an input dimension for ESDK.
- plaintext: Range of [representative plaintext values](#representative-plaintext-constraints)
- commitment policy: Range of allowed [commitment policies](../../client-apis/client.md#commitment-policy)
- frame size: Range of [representative frame sizes](#representative-frame-sizes)
- maximum encrypted data keys: Range of [representative number of maximum encrypted data keys](#representative-number-of-maximum-encrypted-data-keys-edks)

## Evaluation rules

- Every [MPL evaluation rule](mpl-test-vector-enumeration.md#evaluation-rules) is an evaluation rule for ESDK.

## Representative values

### Representative frame sizes

- Non-framed data: `frame size = 0`
- The representative frame size value for non-framed data
MUST have frame size = 0.
- Small frame: `0 < frame size < 4096`
- The representative value for a small frame
MUST have frame size between 0 and 4096.
- Default frame: `frame size = 4096`
- The representative value for the default frame size
MUST have frame size = 4096.
- Large frame: `frame size > 4096`
- The representative value for a large frame
MUST have frame size greater than 4096.

### Representative plaintext constraints

#### Framed data

These MUST only be used if `frame size > 0`.

- Empty: `length = 0`
- The representative plaintext value for empty framed data
MUST have length = 0.
- Small: `0 < length < 10`
- The representative plaintext value for small framed data
MUST have length between 0 and 10.
- If `frame size < 10`, omit this.
- Medium: `10 ≤ length < 1000`
- The representative plaintext value for medium framed data
MUST have length of at least 10 and less than 1000.
- If `frame size < 1000`, omit this.
- Large: `1000 ≤ length <` [frame size](#representative-frame-sizes)
- The representative plaintext value for large framed data
MUST have length of at least 1000 and less than the configured frame size.
- Largest frame: `length = frame size`
- The representative plaintext value for the largest frame
MUST have length equal to the configured frame size.
- Largest frame + partial frame: `frame size < length < 2\*(frame size)`
- The representative plaintext value for a largest frame plus partial frame
MUST have length between the configured frame size
and twice the configured frame size.
- Two largest frames: `length = 2\*(frame size)`
- The representative plaintext value for two largest frames
MUST have length equal to twice the configured frame size.
- Many frames: `2*(frame size) < length < (frame size)\*(maximum # of frames)`
- The representative plaintext value for many frames
MUST have length between twice the configured frame size
and ((the configured maximum number of frames) times (the configured frame size)).
- Maximum frames: `length = (frame size)\*(maximum # of frames)`
- The representative plaintext value for maximum frames
MUST have length equal to the configured maximum number of frames times the configured frame size.

#### Non-framed data

These MUST only be used if `frame length = 0`.

- Empty: `length = 0`
- The representative plaintext value for empty non-framed data
MUST have length equal to 0.
- Small: `0 < length < 10`
- The representative plaintext value for small non-framed data
MUST have length between 0 and 10.
- Medium: `10 ≤ length < 1000`
- The representative plaintext value for empty non-framed data
MUST have length of at least 10 and less than 1000.
- Large: `1000 < length ≤ 2^32`
- The representative plaintext value for empty non-framed data
MUST have length of at least 1000 and less than 2^32.

### Representative number of maximum encrypted data keys (EDKs)

- No configured value
- The representative value for no configured maxiumum number of EDKs
MUST be some unset value
that is interpreted as "no maximum value" by the ESDK implementation.
- Zero: `max EDKs = 0`
- The representative value for zero maximum EDKs
MUST have length = 0.
- One: `max EDKs = 1`
- The representative value for one maximum EDK
MUST have length = 1.
- Few: `1 < max EDKs < 10`
- The representative value for few maximum EDKs
MUST have length between 1 and 10.
- Many: `10 ≤ max EDKs`
- The representative value for many maximum EDKs
MUST have length of at least 10.
24 changes: 24 additions & 0 deletions framework/test-vectors/mpl-test-vector-enumeration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved."
[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0"

# MPL Test Vector Enumeration

This document performs the [test vector enumeration](test-vector-enumeration.md) process for the MPL
to construct the full suite of test vectors
for the MPL.

The full suite of test vectors can be constructed
by [enumerating all input configurations](test-vector-enumeration.md#enumerating-input-configurations) from this spec's input dimensions
and [evaluating each configuration's expected result](test-vector-enumeration.md#determining-expected-results) from this spec's evaluation rules.

## Input dimensions

This section enumerates the [input dimensions](../test-vectors/test-vector-enumeration.md#input-dimensions)
for MPL test vectors:

- algorithm suite ID: Range of supported [Algorithm IDs](../algorithm-suites.md#algorithm-suite-id)
- encryption context: Range of [representative encryption context values](./complete-vectors/encryption-context.md)
- required encryption context keys: Range of every [representative required encryption context key](#representative-required-encryption-context-keys)
- reproduced encryption context: Range is every [representative reproduced encryption context](#representative-reproduced-encryption-context)
- encrypt key description: Range of all [key descriptions](./key-description.md) used to request encrypt materials
- decrypt key description: Range of all [key descriptions](./key-description.md) used to decrypt
Loading
Loading