Skip to content

fix: 192 bit algorithm suite support in browsers #131

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 2 commits into from
Jul 9, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ export class WebCryptoDefaultCryptographicMaterialsManager implements WebCryptoM
async getEncryptionMaterials ({ suite, encryptionContext }: WebCryptoEncryptionRequest): Promise<WebCryptoEncryptionResponse> {
suite = suite || new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384)
const material = new WebCryptoEncryptionMaterial(suite)
/* Precondition: Browsers do not support 192 bit keys so I do not support encrypt.
* This is primarily an error in decrypt but this make it clear.
* The error can manifest deep in the decrypt loop making it hard to debug.
*/
needs(suite.keyLength !== 192, '192-bit AES keys are not supported')

const context = await this._generateSigningKeyAndUpdateEncryptionContext(material, encryptionContext)

Expand All @@ -69,10 +64,6 @@ export class WebCryptoDefaultCryptographicMaterialsManager implements WebCryptoM
}

async decryptMaterials ({ suite, encryptedDataKeys, encryptionContext }: WebCryptoDecryptionRequest): Promise<WebCryptoDecryptionResponse> {
/* Precondition: Browsers do not support 192 bit keys, do not attempt decrypt.
* The error can manifest deep in the decrypt loop making it hard to debug.
*/
needs(suite.keyLength !== 192, '192-bit AES keys are not supported')
const material = await this._loadVerificationKeyFromEncryptionContext(new WebCryptoDecryptionMaterial(suite), encryptionContext)

await this.keyring.onDecrypt(material, encryptedDataKeys.slice(), encryptionContext)
Expand Down
31 changes: 31 additions & 0 deletions modules/material-management/src/web_crypto_algorithms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
IWebCryptoAlgorithmSuite, WebCryptoEncryption, WebCryptoHash, // eslint-disable-line no-unused-vars
WebCryptoECDHCurve, AlgorithmSuiteTypeWebCrypto // eslint-disable-line no-unused-vars
} from './algorithm_suites'
import { needs } from './needs'

/* References to https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/algorithms-reference.html
* These are the composed parameters for each algorithm suite specification for
Expand All @@ -41,6 +42,7 @@ const webCryptoAlgAes128GcmIv12Tag16: IWebCryptoAlgorithmSuite = {
tagLength: 128,
cacheSafe: false
}
/* Web browsers do not support 192 bit key lengths at this time. */
const webCryptoAlgAes192GcmIv12Tag16: IWebCryptoAlgorithmSuite = {
id: AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16,
encryption: 'AES-GCM',
Expand All @@ -67,6 +69,7 @@ const webCryptoAlgAes128GcmIv12Tag16HkdfSha256: IWebCryptoAlgorithmSuite = {
kdfHash: 'SHA-256',
cacheSafe: true
}
/* Web browsers do not support 192 bit key lengths at this time. */
const webCryptoAlgAes192GcmIv12Tag16HkdfSha256: IWebCryptoAlgorithmSuite = {
id: AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256,
encryption: 'AES-GCM',
Expand Down Expand Up @@ -99,6 +102,7 @@ const webCryptoAlgAes128GcmIv12Tag16HkdfSha256EcdsaP256: IWebCryptoAlgorithmSuit
signatureCurve: 'P-256',
signatureHash: 'SHA-256'
}
/* Web browsers do not support 192 bit key lengths at this time. */
const webCryptoAlgAes192GcmIv12Tag16HkdfSha384EcdsaP384: IWebCryptoAlgorithmSuite = {
id: AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
encryption: 'AES-GCM',
Expand Down Expand Up @@ -137,6 +141,28 @@ const webCryptoAlgorithms: WebCryptoAlgorithms = Object.freeze({
[AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384]: Object.freeze(webCryptoAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384)
})

/* Web browsers do not support 192 bit key lengths at this time.
* To maintain type compatibility and TypeScript happiness between Algorithm Suites
* I need to have the same list of AlgorithmSuiteIdentifier.
* This list is maintained here to make sure that the error message is helpful.
*/
type WebCryptoAlgorithmSuiteIdentifier = Exclude<Exclude<Exclude<AlgorithmSuiteIdentifier,
AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16>,
AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256>,
AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384>
type SupportedWebCryptoAlgorithms = Readonly<{[id in WebCryptoAlgorithmSuiteIdentifier]: IWebCryptoAlgorithmSuite}>
const supportedWebCryptoAlgorithms: SupportedWebCryptoAlgorithms = Object.freeze({
[AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16]: Object.freeze(webCryptoAlgAes128GcmIv12Tag16),
// [AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16]: Object.freeze(webCryptoAlgAes192GcmIv12Tag16),
[AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16]: Object.freeze(webCryptoAlgAes256GcmIv12Tag16),
[AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256]: Object.freeze(webCryptoAlgAes128GcmIv12Tag16HkdfSha256),
// [AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256]: Object.freeze(webCryptoAlgAes192GcmIv12Tag16HkdfSha256),
[AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256]: Object.freeze(webCryptoAlgAes256GcmIv12Tag16HkdfSha256),
[AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256]: Object.freeze(webCryptoAlgAes128GcmIv12Tag16HkdfSha256EcdsaP256),
// [AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384]: Object.freeze(webCryptoAlgAes192GcmIv12Tag16HkdfSha384EcdsaP384),
[AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384]: Object.freeze(webCryptoAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384)
})

export class WebCryptoAlgorithmSuite extends AlgorithmSuite implements IWebCryptoAlgorithmSuite {
encryption!: WebCryptoEncryption
kdfHash?: WebCryptoHash
Expand All @@ -145,6 +171,11 @@ export class WebCryptoAlgorithmSuite extends AlgorithmSuite implements IWebCrypt
type: AlgorithmSuiteTypeWebCrypto = 'webCrypto'
constructor (id: AlgorithmSuiteIdentifier) {
super(webCryptoAlgorithms[id])
/* Precondition: Browsers do not support 192 bit keys so the AlgorithmSuiteIdentifier is removed.
* This is primarily an error in decrypt but this make it clear.
* The error can manifest deep in the decrypt loop making it hard to debug.
*/
needs(supportedWebCryptoAlgorithms.hasOwnProperty(id), '192-bit AES keys are not supported')
Object.setPrototypeOf(this, WebCryptoAlgorithmSuite.prototype)
Object.freeze(this)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,10 @@ describe('WebCryptoAlgorithmSuite', () => {
expect(Object.isFrozen(WebCryptoAlgorithmSuite)).to.equal(true)
expect(Object.isFrozen(WebCryptoAlgorithmSuite.prototype)).to.equal(true)
})

it('Precondition: Browsers do not support 192 bit keys so the AlgorithmSuiteIdentifier is removed.', () => {
expect(() => new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16)).to.throw()
expect(() => new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256)).to.throw()
expect(() => new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384)).to.throw()
})
})