Skip to content

Commit 0d22709

Browse files
committed
feat(BKS & BKSA)!: Smithy Model for HV-2 (#1350)
BREAKING CHANGE: Branch Key Store Admin has the following breaking changes for MRK support: - `KmsSymmetricKeyArn` has changed the MRK type from String to a `KmsMRKey` - `KmsMRKey` is a new type that allows for proper MRK logic Note that this MRK support is not completed yet. The `CreateKey` and `VersionKey` operations will throw an `UnsupportedFeatureException` if the MRK option is passed.
1 parent 5e55f9c commit 0d22709

File tree

82 files changed

+3622
-871
lines changed

Some content is hidden

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

82 files changed

+3622
-871
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: 17 additions & 8 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 := [];
@@ -192,16 +195,21 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
192195
nameonly logicalKeyStoreName: string ,
193196
nameonly storage: AwsCryptographyKeyStoreTypes.Storage
194197
)
198+
datatype KmsMRKey = | KmsMRKey (
199+
nameonly KeyArn: ComAmazonawsKmsTypes.KeyIdType ,
200+
nameonly Region: ComAmazonawsKmsTypes.RegionType
201+
)
195202
datatype KmsSymmetricEncryption = | KmsSymmetricEncryption (
196203
nameonly KmsArn: ComAmazonawsKmsTypes.KeyIdType ,
197204
nameonly AwsKms: AwsCryptographyKeyStoreTypes.AwsKms
198205
)
199206
datatype KmsSymmetricKeyArn =
200207
| KmsKeyArn(KmsKeyArn: string)
201-
| KmsMRKeyArn(KmsMRKeyArn: string)
202-
datatype MutableBranchKeyProperties = | MutableBranchKeyProperties (
208+
| KmsMRKey(KmsMRKey: KmsMRKey)
209+
datatype MutableBranchKeyContext = | MutableBranchKeyContext (
203210
nameonly KmsArn: string ,
204-
nameonly CustomEncryptionContext: AwsCryptographyKeyStoreTypes.EncryptionContextString
211+
nameonly EncryptionContext: AwsCryptographyKeyStoreTypes.EncryptionContextString ,
212+
nameonly HierarchyVersion: AwsCryptographyKeyStoreTypes.HierarchyVersion
205213
)
206214
datatype MutatedBranchKeyItem = | MutatedBranchKeyItem (
207215
nameonly ItemType: string ,
@@ -216,8 +224,8 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
216224
nameonly MutationToken: MutationToken
217225
)
218226
datatype MutationDetails = | MutationDetails (
219-
nameonly Original: MutableBranchKeyProperties ,
220-
nameonly Terminal: MutableBranchKeyProperties ,
227+
nameonly Original: MutableBranchKeyContext ,
228+
nameonly Terminal: MutableBranchKeyContext ,
221229
nameonly Input: Mutations ,
222230
nameonly SystemKey: string ,
223231
nameonly CreateTime: string ,
@@ -228,7 +236,8 @@ module {:extern "software.amazon.cryptography.keystoreadmin.internaldafny.types"
228236
| No(No: string)
229237
datatype Mutations = | Mutations (
230238
nameonly TerminalKmsArn: Option<string> := Option.None ,
231-
nameonly TerminalEncryptionContext: Option<AwsCryptographyKeyStoreTypes.EncryptionContextString> := Option.None
239+
nameonly TerminalEncryptionContext: Option<AwsCryptographyKeyStoreTypes.EncryptionContextString> := Option.None ,
240+
nameonly TerminalHierarchyVersion: Option<AwsCryptographyKeyStoreTypes.HierarchyVersion> := Option.None
232241
)
233242
datatype MutationToken = | MutationToken (
234243
nameonly Identifier: string ,

0 commit comments

Comments
 (0)