From 5d1ae29bd01f86258b9b8eb001fc269c6d4ae5ed Mon Sep 17 00:00:00 2001 From: Ryan Emery Date: Mon, 19 Aug 2019 12:39:45 -0700 Subject: [PATCH 1/7] fix: BYTES_PER_KEY value Maximum number of bytes which are allowed to be encrypted under a single data key The _real_ maximum is 2 ** 63 - 1, However Javascript can only perform safe operations on values up to Number.MAX_SAFE_INTEGER === 9007199254740991 === 2 ** 53 - 1. e.g Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 => true Number.MAX_SAFE_INTEGER + 1 > Number.MAX_SAFE_INTEGER + 2 => false Number.MAX_SAFE_INTEGER + 1 < Number.MAX_SAFE_INTEGER + 2 => false This means that after 2 ** 53 - 1 the process of accumulating a byte count will never yield an accurate comparison and so, never halt. The choice here to use 2 ** 53 - 1 instead of Number.MAX_SAFE_INTEGER is deliberate. This is because in the future Number.MAX_SAFE_INTEGER could be raised to 2 ** 66 or some value larger 2 ** 63. --- modules/serialize/src/identifiers.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/modules/serialize/src/identifiers.ts b/modules/serialize/src/identifiers.ts index a92e28318..dbe6dcf61 100644 --- a/modules/serialize/src/identifiers.ts +++ b/modules/serialize/src/identifiers.ts @@ -62,8 +62,23 @@ Object.freeze(SequenceIdentifier) export enum Maximum { // Maximum number of messages which are allowed to be encrypted under a single cached data key MESSAGES_PER_KEY = 2 ** 32, // eslint-disable-line no-unused-vars - // Maximum number of bytes which are allowed to be encrypted under a single cached data key - BYTES_PER_KEY = 2 ** 63 - 1, // eslint-disable-line no-unused-vars + /* Maximum number of bytes which are allowed to be encrypted under a single data key + * The _real_ maximum is 2 ** 63 - 1, + * However Javascript can only perform safe operations on values + * up to Number.MAX_SAFE_INTEGER === 9007199254740991 === 2 ** 53 - 1. + * e.g + * Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 => true + * Number.MAX_SAFE_INTEGER + 1 > Number.MAX_SAFE_INTEGER + 2 => false + * Number.MAX_SAFE_INTEGER + 1 < Number.MAX_SAFE_INTEGER + 2 => false + * + * This means that after 2 ** 53 - 1 the process of accumulating a byte count + * will never yield an accurate comparison and so, never halt. + * + * The choice here to use 2 ** 53 - 1 instead of Number.MAX_SAFE_INTEGER is deliberate. + * This is because in the future Number.MAX_SAFE_INTEGER could be raised to 2 ** 66 + * or some value larger 2 ** 63. + */ + BYTES_PER_KEY = 2 ** 53 - 1, // eslint-disable-line no-unused-vars // Maximum number of frames allowed in one message as defined in specification FRAME_COUNT = 2 ** 32 - 1, // eslint-disable-line no-unused-vars // Maximum bytes allowed in a single frame as defined in specification From 9d66051790cd2224c8994ae60dfd7d91bf5a6684 Mon Sep 17 00:00:00 2001 From: Ryan Emery Date: Thu, 22 Aug 2019 15:46:59 -0700 Subject: [PATCH 2/7] update comment --- modules/serialize/src/identifiers.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/serialize/src/identifiers.ts b/modules/serialize/src/identifiers.ts index dbe6dcf61..1ac620136 100644 --- a/modules/serialize/src/identifiers.ts +++ b/modules/serialize/src/identifiers.ts @@ -62,7 +62,8 @@ Object.freeze(SequenceIdentifier) export enum Maximum { // Maximum number of messages which are allowed to be encrypted under a single cached data key MESSAGES_PER_KEY = 2 ** 32, // eslint-disable-line no-unused-vars - /* Maximum number of bytes which are allowed to be encrypted under a single data key + /* Maximum number of bytes which are allowed to be encrypted + * under a cached single data key across messages. * The _real_ maximum is 2 ** 63 - 1, * However Javascript can only perform safe operations on values * up to Number.MAX_SAFE_INTEGER === 9007199254740991 === 2 ** 53 - 1. @@ -77,6 +78,16 @@ export enum Maximum { * The choice here to use 2 ** 53 - 1 instead of Number.MAX_SAFE_INTEGER is deliberate. * This is because in the future Number.MAX_SAFE_INTEGER could be raised to 2 ** 66 * or some value larger 2 ** 63. + * + * This is *not* the maximum amount of data that can be encrypted under a single data key + * or under a single AES operation. + * The maximum amount of data that can be safely encrypted under a single AES operation is 2 ** 36 -32. + * However the AWS Encryption SDK for Javascript does not support non-framed encryption. + * Therefore the largest single AES operation supported + * by the AWS Encryption SDK for Javascript is the maximum frame size 2 **32 -1. + * The maximum amount of data that can be encrypted by the AWS Encryption SDK + * is the maximum number of frames at the maximum frame size. + * (number of frames) * (frame size) == (2 ** 32 - 1) * (2 ** 32 -1) ~ 2 ** 64 ~ 1.8e19 bytes. */ BYTES_PER_KEY = 2 ** 53 - 1, // eslint-disable-line no-unused-vars // Maximum number of frames allowed in one message as defined in specification From 3e94d8362e33527647b20e6681c0b57555e337b3 Mon Sep 17 00:00:00 2001 From: Ryan Emery Date: Fri, 23 Aug 2019 15:40:39 -0700 Subject: [PATCH 3/7] lint --- modules/serialize/src/identifiers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/serialize/src/identifiers.ts b/modules/serialize/src/identifiers.ts index 1ac620136..c42765ae3 100644 --- a/modules/serialize/src/identifiers.ts +++ b/modules/serialize/src/identifiers.ts @@ -78,7 +78,7 @@ export enum Maximum { * The choice here to use 2 ** 53 - 1 instead of Number.MAX_SAFE_INTEGER is deliberate. * This is because in the future Number.MAX_SAFE_INTEGER could be raised to 2 ** 66 * or some value larger 2 ** 63. - * + * * This is *not* the maximum amount of data that can be encrypted under a single data key * or under a single AES operation. * The maximum amount of data that can be safely encrypted under a single AES operation is 2 ** 36 -32. From 4e9cd58513d4ac6fd0cf8aad5fb595d4314ead68 Mon Sep 17 00:00:00 2001 From: seebees Date: Fri, 23 Aug 2019 16:52:25 -0700 Subject: [PATCH 4/7] Update modules/serialize/src/identifiers.ts Co-Authored-By: Matt Bullock --- modules/serialize/src/identifiers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/serialize/src/identifiers.ts b/modules/serialize/src/identifiers.ts index c42765ae3..55e3614b5 100644 --- a/modules/serialize/src/identifiers.ts +++ b/modules/serialize/src/identifiers.ts @@ -63,7 +63,7 @@ export enum Maximum { // Maximum number of messages which are allowed to be encrypted under a single cached data key MESSAGES_PER_KEY = 2 ** 32, // eslint-disable-line no-unused-vars /* Maximum number of bytes which are allowed to be encrypted - * under a cached single data key across messages. + * under a single cached data key across messages. * The _real_ maximum is 2 ** 63 - 1, * However Javascript can only perform safe operations on values * up to Number.MAX_SAFE_INTEGER === 9007199254740991 === 2 ** 53 - 1. From f820a6344a5d3ad7af3d8dd914331a3b65438119 Mon Sep 17 00:00:00 2001 From: seebees Date: Fri, 23 Aug 2019 16:52:32 -0700 Subject: [PATCH 5/7] Update modules/serialize/src/identifiers.ts Co-Authored-By: Matt Bullock --- modules/serialize/src/identifiers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/serialize/src/identifiers.ts b/modules/serialize/src/identifiers.ts index 55e3614b5..ac32a40e4 100644 --- a/modules/serialize/src/identifiers.ts +++ b/modules/serialize/src/identifiers.ts @@ -62,7 +62,7 @@ Object.freeze(SequenceIdentifier) export enum Maximum { // Maximum number of messages which are allowed to be encrypted under a single cached data key MESSAGES_PER_KEY = 2 ** 32, // eslint-disable-line no-unused-vars - /* Maximum number of bytes which are allowed to be encrypted + /* Maximum number of bytes that are allowed to be encrypted * under a single cached data key across messages. * The _real_ maximum is 2 ** 63 - 1, * However Javascript can only perform safe operations on values From 1dcd9fb970f7d9c169adc70c4eef426499cf4649 Mon Sep 17 00:00:00 2001 From: Ryan Emery Date: Tue, 27 Aug 2019 16:02:39 -0700 Subject: [PATCH 6/7] update constant names --- ...caching_cryptographic_materials_decorators.ts | 8 ++++---- modules/serialize/src/identifiers.ts | 16 +++------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/modules/cache-material/src/caching_cryptographic_materials_decorators.ts b/modules/cache-material/src/caching_cryptographic_materials_decorators.ts index b5d0549b2..69db31bd4 100644 --- a/modules/cache-material/src/caching_cryptographic_materials_decorators.ts +++ b/modules/cache-material/src/caching_cryptographic_materials_decorators.ts @@ -49,17 +49,17 @@ export function decorateProperties ( /* Precondition: You *can not* cache something forever. */ needs(maxAge > 0, 'You must configure a maxAge') /* Precondition: maxBytesEncrypted must be inside bounds. i.e. positive and not more than the maximum. */ - needs(!maxBytesEncrypted || (maxBytesEncrypted > 0 && Maximum.BYTES_PER_KEY >= maxBytesEncrypted), 'maxBytesEncrypted is outside of bounds.') + needs(!maxBytesEncrypted || (maxBytesEncrypted > 0 && Maximum.BYTES_PER_CACHED_KEY_LIMIT >= maxBytesEncrypted), 'maxBytesEncrypted is outside of bounds.') /* Precondition: maxMessagesEncrypted must be inside bounds. i.e. positive and not more than the maximum. */ - needs(!maxMessagesEncrypted || (maxMessagesEncrypted > 0 && Maximum.MESSAGES_PER_KEY >= maxMessagesEncrypted), 'maxMessagesEncrypted is outside of bounds.') + needs(!maxMessagesEncrypted || (maxMessagesEncrypted > 0 && Maximum.MESSAGES_PER_CACHED_KEY_LIMIT >= maxMessagesEncrypted), 'maxMessagesEncrypted is outside of bounds.') /* Precondition: partition must be a string. */ needs(partition && typeof partition === 'string', 'partition must be a string.') readOnlyProperty(obj, '_cache', cache) readOnlyProperty(obj, '_backingMaterialsManager', backingMaterialsManager) readOnlyProperty(obj, '_maxAge', maxAge) - readOnlyProperty(obj, '_maxBytesEncrypted', maxBytesEncrypted || Maximum.BYTES_PER_KEY) - readOnlyProperty(obj, '_maxMessagesEncrypted', maxMessagesEncrypted || Maximum.MESSAGES_PER_KEY) + readOnlyProperty(obj, '_maxBytesEncrypted', maxBytesEncrypted || Maximum.BYTES_PER_CACHED_KEY_LIMIT) + readOnlyProperty(obj, '_maxMessagesEncrypted', maxMessagesEncrypted || Maximum.MESSAGES_PER_CACHED_KEY_LIMIT) readOnlyProperty(obj, '_partition', partition) } diff --git a/modules/serialize/src/identifiers.ts b/modules/serialize/src/identifiers.ts index ac32a40e4..34fd2f3e3 100644 --- a/modules/serialize/src/identifiers.ts +++ b/modules/serialize/src/identifiers.ts @@ -61,10 +61,10 @@ Object.freeze(SequenceIdentifier) export enum Maximum { // Maximum number of messages which are allowed to be encrypted under a single cached data key - MESSAGES_PER_KEY = 2 ** 32, // eslint-disable-line no-unused-vars + MESSAGES_PER_CACHED_KEY_LIMIT = 2 ** 32, // eslint-disable-line no-unused-vars /* Maximum number of bytes that are allowed to be encrypted * under a single cached data key across messages. - * The _real_ maximum is 2 ** 63 - 1, + * The maximum value in some versions of the AWS Encryption SDK is 2 ** 63 - 1, * However Javascript can only perform safe operations on values * up to Number.MAX_SAFE_INTEGER === 9007199254740991 === 2 ** 53 - 1. * e.g @@ -78,18 +78,8 @@ export enum Maximum { * The choice here to use 2 ** 53 - 1 instead of Number.MAX_SAFE_INTEGER is deliberate. * This is because in the future Number.MAX_SAFE_INTEGER could be raised to 2 ** 66 * or some value larger 2 ** 63. - * - * This is *not* the maximum amount of data that can be encrypted under a single data key - * or under a single AES operation. - * The maximum amount of data that can be safely encrypted under a single AES operation is 2 ** 36 -32. - * However the AWS Encryption SDK for Javascript does not support non-framed encryption. - * Therefore the largest single AES operation supported - * by the AWS Encryption SDK for Javascript is the maximum frame size 2 **32 -1. - * The maximum amount of data that can be encrypted by the AWS Encryption SDK - * is the maximum number of frames at the maximum frame size. - * (number of frames) * (frame size) == (2 ** 32 - 1) * (2 ** 32 -1) ~ 2 ** 64 ~ 1.8e19 bytes. */ - BYTES_PER_KEY = 2 ** 53 - 1, // eslint-disable-line no-unused-vars + BYTES_PER_CACHED_KEY_LIMIT = 2 ** 53 - 1, // eslint-disable-line no-unused-vars // Maximum number of frames allowed in one message as defined in specification FRAME_COUNT = 2 ** 32 - 1, // eslint-disable-line no-unused-vars // Maximum bytes allowed in a single frame as defined in specification From 5a15639c7b4b14208d351c3161c75314194e8440 Mon Sep 17 00:00:00 2001 From: seebees Date: Tue, 27 Aug 2019 18:13:03 -0700 Subject: [PATCH 7/7] Update modules/serialize/src/identifiers.ts Co-Authored-By: Matt Bullock --- modules/serialize/src/identifiers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/serialize/src/identifiers.ts b/modules/serialize/src/identifiers.ts index 34fd2f3e3..6da3c56a5 100644 --- a/modules/serialize/src/identifiers.ts +++ b/modules/serialize/src/identifiers.ts @@ -64,7 +64,7 @@ export enum Maximum { MESSAGES_PER_CACHED_KEY_LIMIT = 2 ** 32, // eslint-disable-line no-unused-vars /* Maximum number of bytes that are allowed to be encrypted * under a single cached data key across messages. - * The maximum value in some versions of the AWS Encryption SDK is 2 ** 63 - 1, + * The maximum value defined in the AWS Encryption SDK specification is 2 ** 63 - 1. * However Javascript can only perform safe operations on values * up to Number.MAX_SAFE_INTEGER === 9007199254740991 === 2 ** 53 - 1. * e.g