Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit be3e77c

Browse files
committedDec 23, 2024·
add logicalKeyStoreName
1 parent 59862ee commit be3e77c

File tree

5 files changed

+72
-19
lines changed

5 files changed

+72
-19
lines changed
 

‎DynamoDbEncryption/dafny/DynamoDbEncryption/src/ConfigToInfo.dfy

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ module SearchConfigToInfo {
3939
returns (output : Result<Option<I.ValidSearchInfo>, Error>)
4040
requires ValidSearchConfig(outer.search)
4141
requires outer.search.Some? ==> ValidSharedCache(outer.search.value.versions[0].keySource)
42+
modifies if outer.search.Some? then outer.search.value.versions[0].keyStore.Modifies else {}
4243
ensures output.Success? && output.value.Some? ==>
4344
&& output.value.value.ValidState()
4445
&& fresh(output.value.value.versions[0].keySource.client)
@@ -57,7 +58,8 @@ module SearchConfigToInfo {
5758
} else {
5859
:- Need(outer.search.value.writeVersion == 1, E("writeVersion must be '1'."));
5960
:- Need(|outer.search.value.versions| == 1, E("search config must be have exactly one version."));
60-
var version :- ConvertVersion(outer, outer.search.value.versions[0]);
61+
var beaconVersionConfig := outer.search.value.versions[0];
62+
var version :- ConvertVersion(outer, beaconVersionConfig);
6163
var info := I.MakeSearchInfo(version);
6264
return Success(Some(info));
6365
}
@@ -115,6 +117,7 @@ module SearchConfigToInfo {
115117
)
116118
returns (output : Result<I.KeySource, Error>)
117119
modifies client.Modifies
120+
modifies keyStore.Modifies
118121
requires client.ValidState()
119122
requires ValidSharedCache(config)
120123
ensures client.ValidState()
@@ -203,16 +206,25 @@ module SearchConfigToInfo {
203206
);
204207
}
205208
else {
206-
partitionIdBytes :- I.GeneratePartitionId();
209+
partitionIdBytes :- I.GenerateUuidBytes();
207210
}
211+
var getKeyStoreInfoOutput? := keyStore.GetKeyStoreInfo();
212+
var getKeyStoreInfoOutput :- getKeyStoreInfoOutput?.MapFailure(e => Error.AwsCryptographyKeyStore(e));
213+
var logicalKeyStoreName : string := getKeyStoreInfoOutput.logicalKeyStoreName;
214+
var logicalKeyStoreNameBytes : seq<uint8> :- UTF8.Encode(logicalKeyStoreName)
215+
.MapFailure(
216+
e => Error.DynamoDbEncryptionException(
217+
message := "Could not UTF-8 Encode Logical Key Store Name: " + e
218+
)
219+
);
208220

209221
if config.multi? {
210222
:- Need(0 < config.multi.cacheTTL, E("Beacon Cache TTL must be at least 1."));
211223
var deleteKey :- ShouldDeleteKeyField(outer, config.multi.keyFieldName);
212-
output := Success(I.KeySource(client, keyStore, I.MultiLoc(config.multi.keyFieldName, deleteKey), cache, config.multi.cacheTTL as uint32, partitionIdBytes));
224+
output := Success(I.KeySource(client, keyStore, I.MultiLoc(config.multi.keyFieldName, deleteKey), cache, config.multi.cacheTTL as uint32, partitionIdBytes, logicalKeyStoreNameBytes));
213225
} else {
214226
:- Need(0 < config.single.cacheTTL, E("Beacon Cache TTL must be at least 1."));
215-
output := Success(I.KeySource(client, keyStore, I.SingleLoc(config.single.keyId), cache, config.single.cacheTTL as uint32, partitionIdBytes));
227+
output := Success(I.KeySource(client, keyStore, I.SingleLoc(config.single.keyId), cache, config.single.cacheTTL as uint32, partitionIdBytes, logicalKeyStoreNameBytes));
216228
}
217229
}
218230

@@ -221,6 +233,7 @@ module SearchConfigToInfo {
221233
returns (output : Result<I.ValidBeaconVersion, Error>)
222234
requires ValidBeaconVersion(config)
223235
requires ValidSharedCache(config.keySource)
236+
modifies config.keyStore.Modifies
224237
ensures output.Success? ==>
225238
&& output.value.ValidState()
226239
&& fresh(output.value.keySource.client)

‎DynamoDbEncryption/dafny/DynamoDbEncryption/src/SearchInfo.dfy

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,18 +129,18 @@ module SearchableEncryptionInfo {
129129
return Success(newKey);
130130
}
131131

132-
// Generates a new partitionId, which is a random UUID
133-
method GeneratePartitionId() returns (output : Result<seq<uint8>, Error>)
132+
// Generates a new random UUID converted to UTF8 bytes
133+
method GenerateUuidBytes() returns (output : Result<seq<uint8>, Error>)
134134
{
135135
var uuid? := UUID.GenerateUUID();
136136

137137
var uuid :- uuid?
138138
.MapFailure(e => Error.DynamoDbEncryptionException(message := e));
139139

140-
var partitionIdBytes: seq<uint8> :- UUID.ToByteArray(uuid)
140+
var uuidBytes: seq<uint8> :- UUID.ToByteArray(uuid)
141141
.MapFailure(e => Error.DynamoDbEncryptionException(message := e));
142142

143-
output := Success(partitionIdBytes);
143+
output := Success(uuidBytes);
144144
}
145145

146146
datatype KeyLocation =
@@ -154,7 +154,8 @@ module SearchableEncryptionInfo {
154154
keyLoc : KeyLocation,
155155
cache : MP.ICryptographicMaterialsCache,
156156
cacheTTL : uint32,
157-
partitionIdBytes : seq<uint8>
157+
partitionIdBytes : seq<uint8>,
158+
logicalKeyStoreNameBytes : seq<uint8>
158159
) {
159160
function Modifies() : set<object> {
160161
client.Modifies + store.Modifies + cache.Modifies
@@ -174,7 +175,7 @@ module SearchableEncryptionInfo {
174175
if keyLoc.SingleLoc? {
175176
:- Need(keyId.DontUseKeyId?, E("KeyID should not be supplied with a SingleKeyStore"));
176177
var now := Time.GetCurrent();
177-
var theMap :- getKeysCache(stdNames, keyLoc.keyId, cacheTTL as MP.PositiveLong, partitionIdBytes, now as MP.PositiveLong);
178+
var theMap :- getKeysCache(stdNames, keyLoc.keyId, cacheTTL as MP.PositiveLong, partitionIdBytes, logicalKeyStoreNameBytes, now as MP.PositiveLong);
178179
return Success(Keys(theMap));
179180
} else if keyLoc.LiteralLoc? {
180181
:- Need(keyId.DontUseKeyId?, E("KeyID should not be supplied with a LiteralKeyStore"));
@@ -184,7 +185,7 @@ module SearchableEncryptionInfo {
184185
match keyId {
185186
case DontUseKeyId => return Failure(E("KeyID must not be supplied with a MultiKeyStore"));
186187
case ShouldHaveKeyId => return Success(ShouldHaveKeys);
187-
case KeyId(id) => var now := Time.GetCurrent(); var theMap :- getKeysCache(stdNames, id, cacheTTL as MP.PositiveLong, partitionIdBytes, now as MP.PositiveLong); return Success(Keys(theMap));
188+
case KeyId(id) => var now := Time.GetCurrent(); var theMap :- getKeysCache(stdNames, id, cacheTTL as MP.PositiveLong, partitionIdBytes, logicalKeyStoreNameBytes, now as MP.PositiveLong); return Success(Keys(theMap));
188189
}
189190
}
190191
}
@@ -218,6 +219,7 @@ module SearchableEncryptionInfo {
218219
keyId : string,
219220
cacheTTL : MP.PositiveLong,
220221
partitionIdBytes : seq<uint8>,
222+
logicalKeyStoreNameBytes : seq<uint8>,
221223
now : MP.PositiveLong
222224
)
223225
returns (output : Result<HmacKeyMap, Error>)
@@ -238,7 +240,7 @@ module SearchableEncryptionInfo {
238240
&& var cacheInput := Seq.Last(newHistory).input;
239241
&& var cacheOutput := Seq.Last(newHistory).output;
240242
&& UTF8.Encode(keyId).Success?
241-
&& cacheInput.identifier == RESOURCE_ID_HIERARCHICAL_KEYRING + NULL_BYTE + SCOPE_ID_SEARCHABLE_ENCRYPTION + NULL_BYTE + partitionIdBytes + NULL_BYTE + UTF8.Encode(keyId).value
243+
&& cacheInput.identifier == RESOURCE_ID_HIERARCHICAL_KEYRING + NULL_BYTE + SCOPE_ID_SEARCHABLE_ENCRYPTION + NULL_BYTE + partitionIdBytes + NULL_BYTE + logicalKeyStoreNameBytes + NULL_BYTE + UTF8.Encode(keyId).value
242244

243245
//= specification/searchable-encryption/search-config.md#get-beacon-key-materials
244246
//= type=implication
@@ -297,7 +299,7 @@ module SearchableEncryptionInfo {
297299
// Create the Suffix
298300
var keyIdBytesR := UTF8.Encode(keyId);
299301
var keyIdBytes :- keyIdBytesR.MapFailure(e => E(e));
300-
var suffix : seq<uint8> := keyIdBytes;
302+
var suffix : seq<uint8> := logicalKeyStoreNameBytes + NULL_BYTE + keyIdBytes;
301303

302304
// Append Resource Id, Scope Id, Partition Id, and Suffix to create the cache identifier
303305
var identifier := resourceId + NULL_BYTE + scopeId + NULL_BYTE + partitionIdBytes + NULL_BYTE + suffix;

‎DynamoDbEncryption/dafny/DynamoDbEncryption/test/BeaconTestFixtures.dfy

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,20 @@ module BeaconTestFixtures {
246246
);
247247
var cache :- expect mpl.CreateCryptographicMaterialsCache(input);
248248
// Create a test partitionIdBytes
249-
var partitionIdBytes : seq<uint8> :- expect SI.GeneratePartitionId();
250-
return SI.KeySource(client, version.keyStore, SI.LiteralLoc(keys), cache, 0, partitionIdBytes);
249+
var partitionIdBytes : seq<uint8> :- expect SI.GenerateUuidBytes();
250+
251+
// Create a random logicalKeyStoreNameBytes
252+
// Ideally, this should be taken from the KeyStore version.keyStore,
253+
// but logicalKeyStoreName variable doesn't exist in the
254+
// trait AwsCryptographyKeyStoreTypes.IKeyStoreClient
255+
// Therefore, the only way to get logicalKeyStoreName is
256+
// to call GetKeyStoreInfo, which we don't need to do here
257+
// since this method does NOT test the shared cache
258+
// which is the only place logicalKeyStoreName is used
259+
// (in the cache identifier)
260+
var logicalKeyStoreNameBytes : seq<uint8> :- expect SI.GenerateUuidBytes();
261+
262+
return SI.KeySource(client, version.keyStore, SI.LiteralLoc(keys), cache, 0, partitionIdBytes, logicalKeyStoreNameBytes);
251263
}
252264

253265
method GetMultiSource(keyName : string, version : BeaconVersion) returns (output : SI.KeySource)
@@ -266,8 +278,20 @@ module BeaconTestFixtures {
266278
);
267279
var cache :- expect mpl.CreateCryptographicMaterialsCache(input);
268280
// Create a test partitionIdBytes
269-
var partitionIdBytes : seq<uint8> :- expect SI.GeneratePartitionId();
270-
return SI.KeySource(client, version.keyStore, SI.MultiLoc(keyName, false), cache, 0, partitionIdBytes);
281+
var partitionIdBytes : seq<uint8> :- expect SI.GenerateUuidBytes();
282+
283+
// Create a random logicalKeyStoreNameBytes
284+
// Ideally, this should be taken from the KeyStore version.keyStore,
285+
// but logicalKeyStoreName variable doesn't exist in the
286+
// trait AwsCryptographyKeyStoreTypes.IKeyStoreClient
287+
// Therefore, the only way to get logicalKeyStoreName is
288+
// to call GetKeyStoreInfo, which we don't need to do here
289+
// since this method does NOT test the shared cache
290+
// which is the only place logicalKeyStoreName is used
291+
// (in the cache identifier)
292+
var logicalKeyStoreNameBytes : seq<uint8> :- expect SI.GenerateUuidBytes();
293+
294+
return SI.KeySource(client, version.keyStore, SI.MultiLoc(keyName, false), cache, 0, partitionIdBytes, logicalKeyStoreNameBytes);
271295
}
272296

273297
const SimpleItem : DDB.AttributeMap := map[

‎DynamoDbEncryption/dafny/DynamoDbEncryptionTransforms/src/Index.dfy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ module
130130
(if tableConfig.keyring.Some? then tableConfig.keyring.value.Modifies else {})
131131
+ (if tableConfig.cmm.Some? then tableConfig.cmm.value.Modifies else {})
132132
+ (if tableConfig.legacyOverride.Some? then tableConfig.legacyOverride.value.encryptor.Modifies else {})
133+
+ (if tableConfig.search.Some? then tableConfig.search.value.versions[0].keyStore.Modifies else {})
133134
)
134135
:: o;
135136

@@ -155,6 +156,7 @@ module
155156
assert SearchConfigToInfo.ValidSearchConfig(inputConfig.search);
156157
SearchInModifies(config, tableName);
157158
reveal SearchConfigToInfo.ValidSharedCache();
159+
// TODO: remove assume axiom; this should be generated by smithy-dafny
158160
assume {:axiom} inputConfig.search.Some? ==> SearchConfigToInfo.ValidSharedCache(inputConfig.search.value.versions[0].keySource);
159161
var searchR := SearchConfigToInfo.Convert(inputConfig);
160162
var search :- searchR.MapFailure(e => AwsCryptographyDbEncryptionSdkDynamoDb(e));

‎TestVectors/dafny/DDBEncryption/src/JsonConfig.dfy

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,8 +526,20 @@ module {:options "-functionSyntax:4"} JsonConfig {
526526
var client :- expect Primitives.AtomicPrimitives();
527527

528528
// Create a test partitionIdBytes
529-
var partitionIdBytes : seq<uint8> :- expect SI.GeneratePartitionId();
530-
var src := SI.KeySource(client, store, SI.SingleLoc("foo"), cache, 100 as uint32, partitionIdBytes);
529+
var partitionIdBytes : seq<uint8> :- expect SI.GenerateUuidBytes();
530+
531+
// Create a random logicalKeyStoreNameBytes
532+
// Ideally, this should be taken from the KeyStore store,
533+
// but logicalKeyStoreName variable doesn't exist in the
534+
// trait AwsCryptographyKeyStoreTypes.IKeyStoreClient
535+
// Therefore, the only way to get logicalKeyStoreName is
536+
// to call GetKeyStoreInfo, which we don't need to do here
537+
// since this method does NOT test the shared cache
538+
// which is the only place logicalKeyStoreName is used
539+
// (in the cache identifier)
540+
var logicalKeyStoreNameBytes : seq<uint8> :- expect SI.GenerateUuidBytes();
541+
542+
var src := SI.KeySource(client, store, SI.SingleLoc("foo"), cache, 100 as uint32, partitionIdBytes, logicalKeyStoreNameBytes);
531543

532544
var bv :- expect SI.MakeBeaconVersion(1, src, map[], map[], map[]);
533545
return Success(bv);

0 commit comments

Comments
 (0)
Please sign in to comment.