Skip to content

Commit 768cdca

Browse files
committed
feat(BKS & BKSA): Smithy Model for HV-2 (#1350)
1 parent 528372c commit 768cdca

File tree

65 files changed

+2656
-376
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2656
-376
lines changed

AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/Model/AwsCryptographyKeyStoreTypes.dfy

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ module {:extern "software.amazon.cryptography.keystore.internaldafny.types" } Aw
151151
datatype HierarchicalSymmetric = | HierarchicalSymmetric (
152152
nameonly Version: string
153153
)
154+
datatype HierarchyVersion =
155+
| v1
156+
| v2
154157
type HmacKeyMap = map<string, Secret>
155158
datatype KeyManagement =
156159
| kms(kms: AwsKms)
@@ -924,6 +927,9 @@ module {:extern "software.amazon.cryptography.keystore.internaldafny.types" } Aw
924927
| BranchKeyCiphertextException (
925928
nameonly message: string
926929
)
930+
| HierarchyVersionException (
931+
nameonly message: string
932+
)
927933
| KeyManagementException (
928934
nameonly message: string
929935
)

AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/Model/KeyStore.smithy

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,28 @@ service KeyStore {
6262
errors: [
6363
KeyStoreException
6464
VersionRaceException
65+
KeyManagementException
66+
BranchKeyCiphertextException
67+
HierarchyVersionException
6568
]
6669
}
6770

71+
@documentation(
72+
"The hierarchy-version of a Branch Key;
73+
all items of the same Branch Key SHOULD
74+
have the same hierarchy-version.
75+
The hierarchy-version determines how the Branch Key Store
76+
protects and validates the branch key context (BKC).")
77+
@enum([
78+
{ name: "v1", value: "1" },
79+
{ name: "v2", value: "2" }
80+
])
81+
string HierarchyVersion
82+
83+
// Tony does not think that this shape will be useable, but conceptually, this is what we want
84+
// @documentation("For MPL 1.x, this HierarchyVersion is optional and defaults to \"1\".")
85+
//string HierarchyVersionDefault = "1"
86+
6887
structure KeyStoreConfig {
6988

7089
//= aws-encryption-sdk-specification/framework/branch-key-store.md#initialization
@@ -107,7 +126,7 @@ structure KeyStoreConfig {
107126
@javadoc("The DynamoDB client this Key Store uses to call Amazon DynamoDB. If None is provided and the KMS ARN is, the KMS ARN is used to determine the Region of the default client.")
108127
ddbClient: DdbClientReference,
109128
@javadoc("The KMS client this Key Store uses to call AWS KMS. If None is provided and the KMS ARN is, the KMS ARN is used to determine the Region of the default client.")
110-
kmsClient: KmsClientReference,
129+
kmsClient: KmsClientReference
111130
}
112131

113132
union Storage {
@@ -226,14 +245,33 @@ structure CreateKeyStoreOutput {
226245
tableArn: com.amazonaws.dynamodb#TableArn
227246
}
228247

248+
// TODO : Dev Guide for BKS needs refactoring
229249
// CreateKey will create two keys to add to the key store
230250
// One is the branch key, which is used in the hierarchical keyring
231251
// The second is a beacon key that is used as a root key to
232252
// derive different beacon keys per beacon.
233-
@javadoc("Create a new Branch Key in the Key Store. Additionally create a Beacon Key that is tied to this Branch Key.")
253+
@javadoc(
254+
"Create a new Branch Key in the Branch Key Store.
255+
This method ONLY creates hierarchy-version-1 branch keys.
256+
This creates 3 items: the ACTIVE branch key item, the DECRYPT_ONLY for the ACTIVE branch key item, and the beacon key.
257+
In DynamoDB, the sort-key for the ACTIVE branch key is 'branch:ACTIVE`;
258+
the sort-key for the decrypt_only is 'branch:version:<uuid>';
259+
the sort-key for the beacon key is `beacon:ACTIVE'.
260+
The active branch key and the decrypt_only items have the same plain-text data key.
261+
The beacon key plain-text data key is unqiue.
262+
KMS is called 3 times; GenerateDataKeyWithoutPlaintext is called twice, ReEncrypt is called once.
263+
All three items are written to DDB by a TransactionWriteItems, conditioned on the absence of a conflicting Branch Key ID.
264+
See Branch Key Store Developer Guide's 'Create Branch Keys': https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/create-branch-keys.html")
234265
operation CreateKey {
235266
input: CreateKeyInput,
236267
output: CreateKeyOutput
268+
errors: [
269+
// KmsException https://sdk.amazonaws.com/java/api/2.0.0-preview-11/software/amazon/awssdk/services/kms/model/KmsException.html
270+
// DynamoDbException https://sdk.amazonaws.com/java/api/2.0.0-preview-11/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html
271+
KeyStoreException
272+
KeyManagementException
273+
HierarchyVersionException
274+
]
237275
}
238276

239277
//= aws-encryption-sdk-specification/framework/branch-key-store.md#createkey
@@ -256,14 +294,35 @@ structure CreateKeyOutput {
256294
branchKeyIdentifier: String
257295
}
258296

297+
// TODO : Dev Guide for BKS needs refactoring
259298
// VersionKey will create a new branch key under the
260299
// provided branchKeyIdentifier and rotate the "older" material
261300
// on the key store under the branchKeyIdentifier. This operation MUST NOT
262301
// rotate the beacon key under the branchKeyIdentifier.
263-
@javadoc("Create a new ACTIVE version of an existing Branch Key in the Key Store, and set the previously ACTIVE version to DECRYPT_ONLY.")
302+
@javadoc(
303+
"Rotates an exsisting Branch Key;
304+
this generates a fresh AES-256 key which all future encrypts will use
305+
for the Key Derivation Function,
306+
until VersionKey is executed again.
307+
This method ONLY works with hierarchy-version-1 Branch Keys;
308+
if a hierarchy-version-2 Branch Key is encountered, the operation fails before calling KMS.
309+
Rotation is accomplished by first authenticating the ACTIVE branch key item via 'kms:ReEncrypt'.
310+
'kms:GenerateDataKeyWithoutPlaintext', followed by 'kms:ReEncrypt' is used to create a new ACTIVE and matching DECRYPT_ONLY.
311+
These two items are then writen to the Branch Key Store via a TransactionWriteItems;
312+
this only overwrites the ACTIVE item, the DECRYPT_ONLY is a new item.
313+
This leaves all the previous DECRYPT_ONLY items avabile to service decryption of previous rotations.
314+
See Branch Key Store Developer Guide's 'Rotate your active branch key': https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/rotate-branch-key.html")
264315
operation VersionKey {
265316
input: VersionKeyInput,
266317
output: VersionKeyOutput
318+
errors: [
319+
// KmsException https://sdk.amazonaws.com/java/api/2.0.0-preview-11/software/amazon/awssdk/services/kms/model/KmsException.html
320+
// DynamoDbException https://sdk.amazonaws.com/java/api/2.0.0-preview-11/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html
321+
KeyStoreException
322+
VersionRaceException
323+
KeyManagementException
324+
HierarchyVersionException
325+
]
267326
}
268327

269328
@javadoc("Inputs for versioning a Branch Key.")
@@ -457,18 +516,29 @@ structure KeyManagementException {
457516

458517
@error("client")
459518
@documentation("
460-
The cipher-text or additional authenticated data incorporated into the cipher-text,
519+
The cipher-text or branch key context incorporated into the cipher-text,
461520
such as the encryption context, is corrupted, missing, or otherwise invalid.
462-
For Branch Keys,
463-
the Encryption Context is a combination of:
464-
- the custom encryption context
521+
For branch keys,
522+
the branch key context (BKC) is a combination of:
523+
- the encryption context
465524
- storage identifiers (partition key, sort key, logical name)
466525
- metadata that binds the Branch Key to encrypted data (version)
526+
- create-time
527+
- hierarchy-version
467528
468529
If any of the above are modified without calling KMS,
469-
the Branch Key's cipher-text becomes invalid.
530+
the branch key's cipher-text becomes invalid.
470531
")
471532
structure BranchKeyCiphertextException {
472533
@required
473-
message: String,
534+
message: String
535+
}
536+
537+
@error("client")
538+
@documentation(
539+
"The HierarchyVersion of the Branch Key is not supported by the operation.
540+
'hierarchy-version-2' Branch Keys can only be created or versioned (rotated) via the Branch Key Store Admin.")
541+
structure HierarchyVersionException {
542+
@required
543+
message: String
474544
}

AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/src/CreateKeys.dfy

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,12 @@ module {:options "/functionSyntax:4" } CreateKeys {
495495
Types.KeyStoreException(
496496
message := ErrorMessages.INVALID_ACTIVE_BRANCH_KEY_FROM_STORAGE)
497497
);
498-
498+
// TODO-HV-2-M3: Support Version in HV-2
499+
:- Need(
500+
oldActiveItem.EncryptionContext[Structure.HIERARCHY_VERSION] == Structure.HIERARCHY_VERSION_VALUE_1,
501+
Types.KeyStoreException(
502+
message := "At this time, VersionKey ONLY supports HV-1; BK's Active Item is HV-2.")
503+
);
499504
:- Need(
500505
&& KMSKeystoreOperations.AttemptKmsOperation?(kmsConfiguration, oldActiveItem.EncryptionContext),
501506
Types.KeyStoreException(

AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/src/Index.dfy

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,13 @@ module {:extern "software.amazon.cryptography.keystore.internaldafny"} KeyStore
465465
assert Operations.ValidInternalConfig?(internalConfig);
466466
var client := new KeyStoreClient(internalConfig);
467467

468+
assume {:axiom} fresh(client.Modifies
469+
- ( if config.ddbClient.Some? then config.ddbClient.value.Modifies else {})
470+
- ( if config.kmsClient.Some? then config.kmsClient.value.Modifies else {})
471+
- ( if (config.storage.Some? && config.storage.value.custom?) then config.storage.value.custom.Modifies else {})
472+
- ( if (config.keyManagement.Some? && config.keyManagement.value.kms? && config.keyManagement.value.kms.kmsClient.Some?) then config.keyManagement.value.kms.kmsClient.value.Modifies else {})
473+
- ( if (config.storage.Some? && config.storage.value.ddb? && config.storage.value.ddb.ddbClient.Some?) then config.storage.value.ddb.ddbClient.value.Modifies else {}));
474+
468475
return Success(client);
469476
}
470477

AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/src/Structure.dfy

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,14 @@ module {:options "/functionSyntax:4" } Structure {
4141
}
4242

4343
//Attribute Values
44-
const HIERARCHY_VERSION_VALUE := "1"
44+
const HIERARCHY_VERSION_VALUE_1 := "1"
45+
const HIERARCHY_VERSION_VALUE_2 := "2"
46+
// TODO-HV-2-M1 : Find all HIERARCHY_VERSION_VALUE and replace them with something
47+
const HIERARCHY_VERSION_VALUE := HIERARCHY_VERSION_VALUE_1
48+
// TODO-HV-2-M1 : Find all HIERARCHY_VERSION_ATTRIBUTE_VALUE and replace them with something
4549
const HIERARCHY_VERSION_ATTRIBUTE_VALUE := DDB.AttributeValue.N(HIERARCHY_VERSION_VALUE)
50+
const HIERARCHY_VERSION_ATTRIBUTE_VALUE_1 := DDB.AttributeValue.N(HIERARCHY_VERSION_VALUE_1)
51+
const HIERARCHY_VERSION_ATTRIBUTE_VALUE_2 := DDB.AttributeValue.N(HIERARCHY_VERSION_VALUE_2)
4652
const BRANCH_KEY_TYPE_PREFIX := "branch:version:"
4753
const BRANCH_KEY_ACTIVE_TYPE := "branch:ACTIVE"
4854
const BEACON_KEY_TYPE_VALUE := "beacon:ACTIVE"

AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStoreAdmin/Model/AwsCryptographyKeyStoreAdminTypes.dfy

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
4141
nameonly Identifier: Option<string> := Option.None ,
4242
nameonly EncryptionContext: Option<AwsCryptographyKeyStoreTypes.EncryptionContext> := Option.None ,
4343
nameonly KmsArn: KmsSymmetricKeyArn ,
44-
nameonly Strategy: Option<KeyManagementStrategy> := Option.None
44+
nameonly Strategy: Option<KeyManagementStrategy> := Option.None ,
45+
nameonly HierarchyVersion: Option<AwsCryptographyKeyStoreTypes.HierarchyVersion> := Option.None
4546
)
4647
datatype CreateKeyOutput = | CreateKeyOutput (
47-
nameonly Identifier: string
48+
nameonly Identifier: string ,
49+
nameonly HierarchyVersion: AwsCryptographyKeyStoreTypes.HierarchyVersion
4850
)
4951
datatype DescribeMutationInput = | DescribeMutationInput (
5052
nameonly Identifier: string
@@ -71,6 +73,7 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
7173
datatype KeyManagementStrategy =
7274
| AwsKmsReEncrypt(AwsKmsReEncrypt: AwsCryptographyKeyStoreTypes.AwsKms)
7375
| AwsKmsDecryptEncrypt(AwsKmsDecryptEncrypt: AwsKmsDecryptEncrypt)
76+
| AwsKmsSimple(AwsKmsSimple: AwsCryptographyKeyStoreTypes.AwsKms)
7477
class IKeyStoreAdminClientCallHistory {
7578
ghost constructor() {
7679
CreateKey := [];
@@ -201,7 +204,8 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
201204
| KmsMRKeyArn(KmsMRKeyArn: string)
202205
datatype MutableBranchKeyProperties = | MutableBranchKeyProperties (
203206
nameonly KmsArn: string ,
204-
nameonly CustomEncryptionContext: AwsCryptographyKeyStoreTypes.EncryptionContextString
207+
nameonly CustomEncryptionContext: AwsCryptographyKeyStoreTypes.EncryptionContextString ,
208+
nameonly HierarchyVersion: AwsCryptographyKeyStoreTypes.HierarchyVersion
205209
)
206210
datatype MutatedBranchKeyItem = | MutatedBranchKeyItem (
207211
nameonly ItemType: string ,
@@ -228,7 +232,8 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
228232
| No(No: string)
229233
datatype Mutations = | Mutations (
230234
nameonly TerminalKmsArn: Option<string> := Option.None ,
231-
nameonly TerminalEncryptionContext: Option<AwsCryptographyKeyStoreTypes.EncryptionContextString> := Option.None
235+
nameonly TerminalEncryptionContext: Option<AwsCryptographyKeyStoreTypes.EncryptionContextString> := Option.None ,
236+
nameonly TerminalHierarchyVersion: Option<AwsCryptographyKeyStoreTypes.HierarchyVersion> := Option.None
232237
)
233238
datatype MutationToken = | MutationToken (
234239
nameonly Identifier: string ,

0 commit comments

Comments
 (0)