| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="../../../resources/js-test.js"></script> |
| <script src="../resources/common.js"></script> |
| </head> |
| <body> |
| <p id="description"></p> |
| <div id="console"></div> |
| |
| <script> |
| description("Tests encrypt/decrypt for AES-GCM"); |
| |
| jsTestIsAsync = true; |
| |
| // These tests come from the NIST GCM test vectors: |
| // http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip |
| // |
| // Both encryption and decryption are expected to work. |
| var kAesGcmSuccessVectors = |
| [ |
| // [Keylen = 128] |
| // [IVlen = 96] |
| // [PTlen = 0] |
| // [AADlen = 0] |
| // [Taglen = 128] |
| { |
| "key": "cf063a34d4a9a76c2c86787d3f96db71", |
| "iv": "113b9785971864c83b01c787", |
| "plainText": "", |
| "cipherText": "", |
| "additionalData": "", |
| "authenticationTag": "72ac8493e3a5228b5d130a69d2510e42" |
| }, |
| |
| // [Keylen = 128] |
| // [IVlen = 96] |
| // [PTlen = 0] |
| // [AADlen = 128] |
| // [Taglen = 120] |
| { |
| "key": "6dfa1a07c14f978020ace450ad663d18", |
| "iv": "34edfa462a14c6969a680ec1", |
| "plainText": "", |
| "cipherText": "", |
| "additionalData": "2a35c7f5f8578e919a581c60500c04f6", |
| "authenticationTag": "751f3098d59cf4ea1d2fb0853bde1c" |
| }, |
| |
| // [Keylen = 128] |
| // [IVlen = 96] |
| // [PTlen = 128] |
| // [AADlen = 128] |
| // [Taglen = 112] |
| { |
| "key": "ed6cd876ceba555706674445c229c12d", |
| "iv": "92ecbf74b765bc486383ca2e", |
| "plainText": "bfaaaea3880d72d4378561e2597a9b35", |
| "cipherText": "bdd2ed6c66fa087dce617d7fd1ff6d93", |
| "additionalData": "95bd10d77dbe0e87fb34217f1a2e5efe", |
| "authenticationTag": "ba82e49c55a22ed02ca67da4ec6f" |
| }, |
| |
| // [Keylen = 256] |
| // [IVlen = 1024] |
| // [PTlen = 408] |
| // [AADlen = 720] |
| // [Taglen = 32] |
| { |
| "key": "e03548984a7ec8eaf0870637df0ac6bc17f7159315d0ae26a764fd224e483810", |
| "iv": "f4feb26b846be4cd224dbc5133a5ae13814ebe19d3032acdd3a006463fdb71e83a9d5d96679f26cc1719dd6b4feb3bab5b4b7993d0c0681f36d105ad3002fb66b201538e2b7479838ab83402b0d816cd6e0fe5857e6f4adf92de8ee72b122ba1ac81795024943b7d0151bbf84ce87c8911f512c397d14112296da7ecdd0da52a", |
| "cipherText": "fda718aa1ec163487e21afc34f5a3a34795a9ee71dd3e7ee9a18fdb24181dc982b29c6ec723294a130ca2234952bb0ef68c0f3", |
| "additionalData": "aab26eb3e7acd09a034a9e2651636ab3868e51281590ecc948355e457da42b7ad1391c7be0d9e82895e506173a81857c3226829fbd6dfb3f9657a71a2934445d7c05fa9401cddd5109016ba32c3856afaadc48de80b8a01b57cb", |
| "authenticationTag": "4795fbe0", |
| "plainText": "69fd0c9da10b56ec6786333f8d76d4b74f8a434195f2f241f088b2520fb5fa29455df9893164fb1638abe6617915d9497a8fe2" |
| } |
| ]; |
| |
| function runAesGcmSuccessTestCase(testCase) |
| { |
| var key = null; |
| var keyData = hexStringToUint8Array(testCase.key); |
| var iv = hexStringToUint8Array(testCase.iv); |
| var additionalData = hexStringToUint8Array(testCase.additionalData); |
| var tag = hexStringToUint8Array(testCase.authenticationTag); |
| var usages = ['encrypt', 'decrypt']; |
| var extractable = false; |
| |
| var tagLengthBits = tag.byteLength * 8; |
| |
| var algorithm = {name: 'aes-gcm', iv: iv, additionalData: additionalData, tagLength: tagLengthBits}; |
| |
| // (1) Import the key |
| return crypto.subtle.importKey('raw', keyData, algorithm, extractable, usages).then(function(result) { |
| key = result; |
| |
| // shouldBe() can only resolve variables in global context. |
| tmpKey = key; |
| shouldEvaluateAs("tmpKey.type", "secret"); |
| shouldEvaluateAs("tmpKey.extractable", false); |
| shouldEvaluateAs("tmpKey.algorithm.name", "AES-GCM"); |
| shouldEvaluateAs("tmpKey.usages.join(',')", "encrypt,decrypt"); |
| |
| // (2) Encrypt. |
| return crypto.subtle.encrypt(algorithm, key, hexStringToUint8Array(testCase.plainText)); |
| }).then(function(result) { |
| bytesShouldMatchHexString("Encryption", testCase.cipherText + testCase.authenticationTag, result); |
| |
| // (3) Decrypt |
| return crypto.subtle.decrypt(algorithm, key, hexStringToUint8Array(testCase.cipherText + testCase.authenticationTag)); |
| }).then(function(result) { |
| bytesShouldMatchHexString("Decryption", testCase.plainText, result); |
| }); |
| } |
| |
| var lastPromise = Promise.resolve(null); |
| |
| kAesGcmSuccessVectors.forEach(function(test) { |
| lastPromise = lastPromise.then(runAesGcmSuccessTestCase.bind(null, test)); |
| }); |
| |
| lastPromise.then(finishJSTest, failAndFinishJSTest); |
| |
| </script> |
| |
| </body> |
| </html> |