in modules/material-management-browser/src/material_helpers.ts [236:280]
function getSubtleFunction(iv: Uint8Array, additionalData: Uint8Array) {
/* Precondition: The length of the IV must match the WebCryptoAlgorithmSuite specification. */
needs(
iv.byteLength === ivLength,
'Iv length does not match algorithm suite specification'
)
return async (data: Uint8Array) => {
if (isCryptoKey(deriveKey) && isFullSupportWebCryptoBackend(backend)) {
const { subtle } = backend
const algorithm = { name: cipherName, iv, additionalData, tagLength }
return subtle[subtleFunctionName](algorithm, deriveKey, data)
} else if (
!isCryptoKey(deriveKey) &&
!isFullSupportWebCryptoBackend(backend)
) {
const { nonZeroByteSubtle, zeroByteSubtle } = backend
const { nonZeroByteCryptoKey, zeroByteCryptoKey } = deriveKey
const algorithm = { name: cipherName, iv, additionalData, tagLength }
/* Precondition: The WebCrypto AES-GCM decrypt API expects the data *and* tag together.
* This means that on decrypt any amount of data less than tagLength is invalid.
* This also means that zero encrypted data will be equal to tagLength.
*/
const dataByteLength =
subtleFunctionName === 'decrypt'
? data.byteLength - tagLength / 8
: data.byteLength
needs(dataByteLength >= 0, 'Invalid data length.')
if (dataByteLength === 0) {
return zeroByteSubtle[subtleFunctionName](
algorithm,
zeroByteCryptoKey,
data
)
} else {
return nonZeroByteSubtle[subtleFunctionName](
algorithm,
nonZeroByteCryptoKey,
data
)
}
}
// This should be impossible
throw new Error('Unknown Error')
}
}