mirror of
https://github.com/servo/servo.git
synced 2025-08-11 00:15:32 +01:00
Update web-platform-tests to revision 346d5b51a122f7bb1c7747064499ef281a0200f7
This commit is contained in:
parent
581c8ba1c8
commit
79b1e6c40c
1728 changed files with 20243 additions and 5349 deletions
154
tests/wpt/web-platform-tests/WebCryptoAPI/digest/digest.js
Normal file
154
tests/wpt/web-platform-tests/WebCryptoAPI/digest/digest.js
Normal file
|
@ -0,0 +1,154 @@
|
|||
|
||||
function run_test() {
|
||||
var subtle = crypto.subtle; // Change to test prefixed implementations
|
||||
|
||||
var sourceData = {
|
||||
empty: new Uint8Array(0),
|
||||
short: new Uint8Array([21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255]),
|
||||
medium: new Uint8Array([182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, 140, 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, 178, 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, 107, 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, 200, 7, 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, 134, 37, 171, 172, 161, 147])
|
||||
};
|
||||
|
||||
sourceData.long = new Uint8Array(1024 * sourceData.medium.byteLength);
|
||||
for (var i=0; i<1024; i++) {
|
||||
sourceData.long.set(sourceData.medium, i * sourceData.medium.byteLength);
|
||||
}
|
||||
|
||||
var digestedData = {
|
||||
"sha-1": {
|
||||
empty: new Uint8Array([218, 57, 163, 238, 94, 107, 75, 13, 50, 85, 191, 239, 149, 96, 24, 144, 175, 216, 7, 9]),
|
||||
short: new Uint8Array([201, 19, 24, 205, 242, 57, 106, 1, 94, 63, 78, 106, 134, 160, 186, 101, 184, 99, 89, 68]),
|
||||
medium: new Uint8Array([229, 65, 6, 8, 112, 235, 22, 191, 51, 182, 142, 81, 245, 19, 82, 104, 147, 152, 103, 41]),
|
||||
long: new Uint8Array([48, 152, 181, 0, 55, 236, 208, 46, 189, 101, 118, 83, 178, 191, 160, 30, 238, 39, 162, 234])
|
||||
},
|
||||
"sha-256": {
|
||||
empty: new Uint8Array([227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85]),
|
||||
short: new Uint8Array([162, 131, 17, 134, 152, 71, 146, 199, 211, 45, 89, 200, 151, 64, 104, 127, 25, 173, 220, 27, 149, 158, 113, 161, 204, 83, 138, 59, 126, 216, 67, 242]),
|
||||
medium: new Uint8Array([83, 83, 103, 135, 126, 240, 20, 215, 252, 113, 126, 92, 183, 132, 62, 89, 182, 26, 238, 98, 199, 2, 156, 236, 126, 198, 193, 47, 217, 36, 224, 228]),
|
||||
long: new Uint8Array([20, 205, 234, 157, 199, 95, 90, 98, 116, 217, 252, 30, 100, 0, 153, 18, 241, 220, 211, 6, 180, 143, 232, 233, 207, 18, 45, 230, 113, 87, 23, 129])
|
||||
},
|
||||
"sha-384": {
|
||||
empty: new Uint8Array([56, 176, 96, 167, 81, 172, 150, 56, 76, 217, 50, 126, 177, 177, 227, 106, 33, 253, 183, 17, 20, 190, 7, 67, 76, 12, 199, 191, 99, 246, 225, 218, 39, 78, 222, 191, 231, 111, 101, 251, 213, 26, 210, 241, 72, 152, 185, 91]),
|
||||
short: new Uint8Array([107, 245, 234, 101, 36, 209, 205, 220, 67, 247, 207, 59, 86, 238, 5, 146, 39, 64, 74, 47, 83, 143, 2, 42, 61, 183, 68, 122, 120, 44, 6, 193, 237, 5, 232, 171, 79, 94, 220, 23, 243, 113, 20, 64, 223, 233, 119, 49]),
|
||||
medium: new Uint8Array([203, 194, 197, 136, 254, 91, 37, 249, 22, 218, 40, 180, 228, 122, 72, 74, 230, 252, 31, 228, 144, 45, 213, 201, 147, 154, 107, 253, 3, 74, 179, 180, 139, 57, 8, 116, 54, 1, 31, 106, 153, 135, 157, 39, 149, 64, 233, 119]),
|
||||
long: new Uint8Array([73, 244, 253, 179, 152, 25, 104, 249, 125, 87, 55, 15, 133, 52, 80, 103, 205, 82, 150, 169, 125, 209, 161, 142, 6, 145, 30, 117, 110, 150, 8, 73, 37, 41, 135, 14, 26, 209, 48, 153, 141, 87, 203, 251, 183, 193, 208, 158])
|
||||
},
|
||||
"sha-512": {
|
||||
empty: new Uint8Array([207, 131, 225, 53, 126, 239, 184, 189, 241, 84, 40, 80, 214, 109, 128, 7, 214, 32, 228, 5, 11, 87, 21, 220, 131, 244, 169, 33, 211, 108, 233, 206, 71, 208, 209, 60, 93, 133, 242, 176, 255, 131, 24, 210, 135, 126, 236, 47, 99, 185, 49, 189, 71, 65, 122, 129, 165, 56, 50, 122, 249, 39, 218, 62]),
|
||||
short: new Uint8Array([55, 82, 72, 190, 95, 243, 75, 231, 76, 171, 79, 241, 195, 188, 141, 198, 139, 213, 248, 223, 244, 2, 62, 152, 248, 123, 134, 92, 255, 44, 114, 66, 146, 223, 24, 148, 67, 166, 79, 244, 19, 74, 101, 205, 70, 53, 185, 212, 245, 220, 13, 63, 182, 117, 40, 0, 42, 99, 172, 242, 108, 157, 165, 117]),
|
||||
medium: new Uint8Array([185, 16, 159, 131, 158, 142, 164, 60, 137, 15, 41, 60, 225, 29, 198, 226, 121, 141, 30, 36, 49, 241, 228, 185, 25, 227, 178, 12, 79, 54, 48, 59, 163, 156, 145, 109, 179, 6, 196, 90, 59, 101, 118, 31, 245, 190, 133, 50, 142, 234, 244, 44, 56, 48, 241, 217, 94, 122, 65, 22, 91, 125, 45, 54]),
|
||||
long: new Uint8Array([75, 2, 202, 246, 80, 39, 96, 48, 234, 86, 23, 229, 151, 197, 213, 63, 217, 218, 166, 139, 120, 191, 230, 11, 34, 170, 184, 211, 106, 76, 42, 58, 255, 219, 113, 35, 79, 73, 39, 103, 55, 197, 117, 221, 247, 77, 20, 5, 76, 189, 111, 219, 152, 253, 13, 220, 188, 180, 111, 145, 173, 118, 182, 238])
|
||||
},
|
||||
}
|
||||
|
||||
// Try every combination of hash with source data size. Variations tested are
|
||||
// hash name in upper, lower, or mixed case, and upper-case version with the
|
||||
// source buffer altered after call.
|
||||
Object.keys(sourceData).forEach(function(size) {
|
||||
Object.keys(digestedData).forEach(function(alg) {
|
||||
var upCase = alg.toUpperCase();
|
||||
var downCase = alg.toLowerCase();
|
||||
var mixedCase = upCase.substr(0, 1) + downCase.substr(1);
|
||||
|
||||
promise_test(function(test) {
|
||||
var promise = subtle.digest({name: upCase}, sourceData[size])
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size);
|
||||
}, function(err) {
|
||||
assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}, upCase + " with " + size + " source data");
|
||||
|
||||
promise_test(function(test) {
|
||||
var promise = subtle.digest({name: mixedCase}, sourceData[size])
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size);
|
||||
}, function(err) {
|
||||
assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message);mixedCase
|
||||
});
|
||||
|
||||
return promise;
|
||||
}, downCase + " with " + size + " source data");
|
||||
|
||||
promise_test(function(test) {
|
||||
var promise = subtle.digest({name: mixedCase}, sourceData[size])
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size);
|
||||
}, function(err) {
|
||||
assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}, mixedCase + " with " + size + " source data");
|
||||
|
||||
promise_test(function(test) {
|
||||
var copiedBuffer = copyBuffer(sourceData[size]);
|
||||
var promise = subtle.digest({name: upCase}, copiedBuffer)
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size);
|
||||
}, function(err) {
|
||||
assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message);
|
||||
});
|
||||
|
||||
copiedBuffer[0] = 255 - copiedBuffer;
|
||||
return promise;
|
||||
}, upCase + " with " + size + " source data and altered buffer after call");
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
// Call digest() with bad algorithm names to get an error
|
||||
var badNames = ["AES-GCM", "RSA-OAEP", "PBKDF2", "AES-KW"];
|
||||
Object.keys(sourceData).forEach(function(size) {
|
||||
badNames.forEach(function(badName) {
|
||||
|
||||
promise_test(function(test) {
|
||||
var promise = subtle.digest({name: badName}, sourceData[size])
|
||||
.then(function(result) {
|
||||
assert_unreached("digest() should not have worked for " + alg + ":" + size);
|
||||
}, function(err) {
|
||||
assert_equals(err.message, "OperationError", "Bad algorithm name should cause OperationError")
|
||||
});
|
||||
|
||||
return promise;
|
||||
}, badName + " with " + size);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
done();
|
||||
|
||||
|
||||
// Returns a copy of the sourceBuffer it is sent.
|
||||
function copyBuffer(sourceBuffer) {
|
||||
var source = new Uint8Array(sourceBuffer);
|
||||
var copy = new Uint8Array(sourceBuffer.byteLength)
|
||||
|
||||
for (var i=0; i<source.byteLength; i++) {
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
function equalBuffers(a, b) {
|
||||
if (a.byteLength !== b.byteLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var aBytes = new Uint8Array(a);
|
||||
var bBytes = new Uint8Array(b);
|
||||
|
||||
for (var i=0; i<a.byteLength; i++) {
|
||||
if (aBytes[i] !== bBytes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("digest.js");
|
||||
|
||||
run_test();
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<title>WebCryptoAPI: digest()</title>
|
||||
<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#dfn-SubtleCrypto-method-digest">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="digest.js"></script>
|
||||
|
||||
<h1>encrypt Tests for digest method</h1>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
run_test();
|
||||
</script>
|
323
tests/wpt/web-platform-tests/WebCryptoAPI/encrypt_decrypt/aes.js
Normal file
323
tests/wpt/web-platform-tests/WebCryptoAPI/encrypt_decrypt/aes.js
Normal file
|
@ -0,0 +1,323 @@
|
|||
|
||||
function run_test() {
|
||||
var subtle = self.crypto.subtle; // Change to test prefixed implementations
|
||||
|
||||
// When are all these tests really done? When all the promises they use have resolved.
|
||||
var all_promises = [];
|
||||
|
||||
// Source file aes_XXX_vectors.js provides the getTestVectors method
|
||||
// for the AES-XXX algorithm that drives these tests.
|
||||
var vectors = getTestVectors();
|
||||
var passingVectors = vectors.passing;
|
||||
var failingVectors = vectors.failing;
|
||||
var decryptionFailingVectors = vectors.decryptionFailing;
|
||||
|
||||
// Check for successful encryption.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKey(vector, ["encrypt", "decrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
return subtle.encrypt(vector.algorithm, vector.key, vector.plaintext)
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, vector.result), "Should return expected result");
|
||||
}, function(err) {
|
||||
assert_unreached("encrypt error for test " + vector.name + ": " + err.message);
|
||||
});
|
||||
}, vector.name);
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step: " + vector.name);
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for successful encryption even if the buffer is changed after calling encrypt.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var plaintext = copyBuffer(vector.plaintext);
|
||||
var promise = importVectorKey(vector, ["encrypt", "decrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.encrypt(vector.algorithm, vector.key, plaintext)
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, vector.result), "Should return expected result");
|
||||
}, function(err) {
|
||||
assert_unreached("encrypt error for test " + vector.name + ": " + err.message);
|
||||
});
|
||||
plaintext[0] = 255 - plaintext[0];
|
||||
return operation;
|
||||
}, vector.name + " with altered plaintext");
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step: " + vector.name + " with altered plaintext");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for successful decryption.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKey(vector, ["encrypt", "decrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
return subtle.decrypt(vector.algorithm, vector.key, vector.result)
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, vector.plaintext), "Should return expected result");
|
||||
}, function(err) {
|
||||
assert_unreached("decrypt error for test " + vector.name + ": " + err.message);
|
||||
});
|
||||
}, vector.name + " decryption");
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step for decryption: " + vector.name);
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for successful decryption even if ciphertext is altered.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var ciphertext = copyBuffer(vector.result);
|
||||
var promise = importVectorKey(vector, ["encrypt", "decrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.decrypt(vector.algorithm, vector.key, ciphertext)
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, vector.plaintext), "Should return expected result");
|
||||
}, function(err) {
|
||||
assert_unreached("decrypt error for test " + vector.name + ": " + err.message);
|
||||
});
|
||||
ciphertext[0] = 255 - ciphertext[0];
|
||||
return operation;
|
||||
}, vector.name + " decryption with altered ciphertext");
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step for decryption: " + vector.name + " with altered ciphertext");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Everything that succeeded should fail if no "encrypt" usage.
|
||||
passingVectors.forEach(function(vector) {
|
||||
// Don't want to overwrite key being used for success tests!
|
||||
var badVector = Object.assign({}, vector);
|
||||
badVector.key = null;
|
||||
|
||||
var promise = importVectorKey(badVector, ["decrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
return subtle.encrypt(vector.algorithm, vector.key, vector.plaintext)
|
||||
.then(function(result) {
|
||||
assert_unreached("should have thrown exception for test " + vector.name);
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should throw an InvalidAccessError instead of " + err.message)
|
||||
});
|
||||
}, vector.name + " without encrypt usage");
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step: " + vector.name + " without encrypt usage");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Encryption should fail if algorithm of key doesn't match algorithm of function call.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var algorithm = Object.assign({}, vector.algorithm);
|
||||
if (algorithm.name === "AES-CBC") {
|
||||
algorithm.name = "AES-CTR";
|
||||
algorithm.counter = new Uint8Array(16);
|
||||
algorithm.length = 64;
|
||||
} else {
|
||||
algorithm.name = "AES-CBC";
|
||||
algorithm.iv = new Uint8Array(16); // Need syntactically valid parameter to get to error being checked.
|
||||
}
|
||||
|
||||
var promise = importVectorKey(vector, ["encrypt", "decrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
return subtle.encrypt(algorithm, vector.key, vector.plaintext)
|
||||
.then(function(result) {
|
||||
assert_unreached("encrypt succeeded despite mismatch " + vector.name + ": " + err.message);
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Mismatch should cause InvalidAccessError instead of " + err.message);
|
||||
});
|
||||
}, vector.name + " with mismatched key and algorithm");
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step: " + vector.name + " with mismatched key and algorithm");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Everything that succeeded decrypting should fail if no "decrypt" usage.
|
||||
passingVectors.forEach(function(vector) {
|
||||
// Don't want to overwrite key being used for success tests!
|
||||
var badVector = Object.assign({}, vector);
|
||||
badVector.key = null;
|
||||
|
||||
var promise = importVectorKey(badVector, ["encrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
return subtle.decrypt(vector.algorithm, vector.key, vector.result)
|
||||
.then(function(result) {
|
||||
assert_unreached("should have thrown exception for test " + vector.name);
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should throw an InvalidAccessError instead of " + err.message)
|
||||
});
|
||||
}, vector.name + " without decrypt usage");
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step: " + vector.name + " without decrypt usage");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for OperationError due to data lengths.
|
||||
failingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKey(vector, ["encrypt", "decrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
return subtle.encrypt(vector.algorithm, vector.key, vector.plaintext)
|
||||
.then(function(result) {
|
||||
assert_unreached("should have thrown exception for test " + vector.name);
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "OperationError", "Should throw an OperationError instead of " + err.message)
|
||||
});
|
||||
}, vector.name);
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step: " + vector.name);
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for OperationError due to data lengths for decryption, too.
|
||||
failingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKey(vector, ["encrypt", "decrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
return subtle.decrypt(vector.algorithm, vector.key, vector.result)
|
||||
.then(function(result) {
|
||||
assert_unreached("should have thrown exception for test " + vector.name);
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "OperationError", "Should throw an OperationError instead of " + err.message)
|
||||
});
|
||||
}, vector.name + " decryption");
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step: decryption " + vector.name);
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for decryption failing for algorithm-specific reasons (such as bad
|
||||
// padding for AES-CBC).
|
||||
decryptionFailingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKey(vector, ["encrypt", "decrypt"])
|
||||
.then(function(vector) {
|
||||
promise_test(function(test) {
|
||||
return subtle.decrypt(vector.algorithm, vector.key, vector.result)
|
||||
.then(function(result) {
|
||||
assert_unreached("should have thrown exception for test " + vector.name);
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "OperationError", "Should throw an OperationError instead of " + err.message)
|
||||
});
|
||||
}, vector.name);
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importKey failed for " + vector.name);
|
||||
}, "importKey step: decryption " + vector.name);
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
Promise.all(all_promises)
|
||||
.then(function() {done();})
|
||||
.catch(function() {done();})
|
||||
|
||||
// A test vector has all needed fields for encryption, EXCEPT that the
|
||||
// key field may be null. This function replaces that null with the Correct
|
||||
// CryptoKey object.
|
||||
//
|
||||
// Returns a Promise that yields an updated vector on success.
|
||||
function importVectorKey(vector, usages) {
|
||||
if (vector.key !== null) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve(vector);
|
||||
});
|
||||
} else {
|
||||
return subtle.importKey("raw", vector.keyBuffer, {name: vector.algorithm.name}, false, usages)
|
||||
.then(function(key) {
|
||||
vector.key = key;
|
||||
return vector;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a copy of the sourceBuffer it is sent.
|
||||
function copyBuffer(sourceBuffer) {
|
||||
var source = new Uint8Array(sourceBuffer);
|
||||
var copy = new Uint8Array(sourceBuffer.byteLength)
|
||||
|
||||
for (var i=0; i<source.byteLength; i++) {
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
function equalBuffers(a, b) {
|
||||
if (a.byteLength !== b.byteLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var aBytes = new Uint8Array(a);
|
||||
var bBytes = new Uint8Array(b);
|
||||
|
||||
for (var i=0; i<a.byteLength; i++) {
|
||||
if (aBytes[i] !== bBytes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("aes_cbc_vectors.js");
|
||||
importScripts("aes.js");
|
||||
|
||||
run_test();
|
|
@ -0,0 +1,261 @@
|
|||
|
||||
// aes_cbc_vectors.js
|
||||
|
||||
// The following function returns an array of test vectors
|
||||
// for the subtleCrypto encrypt method.
|
||||
//
|
||||
// Each test vector has the following fields:
|
||||
// name - a unique name for this vector
|
||||
// keyBuffer - an arrayBuffer with the key data in raw form
|
||||
// key - a CryptoKey object for the keyBuffer. INITIALLY null! You must fill this in first to use it!
|
||||
// algorithm - the value of the AlgorithmIdentifier parameter to provide to encrypt
|
||||
// plaintext - the text to encrypt
|
||||
// result - the expected result (usually just ciphertext, sometimes with added authentication)
|
||||
function getTestVectors() {
|
||||
// Before we can really start, we need to fill a bunch of buffers with data
|
||||
var plaintext = new Uint8Array([84, 104, 105, 115, 32, 115,
|
||||
112, 101, 99, 105, 102, 105, 99, 97, 116, 105, 111, 110,
|
||||
32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32,
|
||||
74, 97, 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80,
|
||||
73, 32, 102, 111, 114, 32, 112, 101, 114, 102, 111, 114,
|
||||
109, 105, 110, 103, 32, 98, 97, 115, 105, 99, 32, 99, 114,
|
||||
121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32,
|
||||
111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105,
|
||||
110, 32, 119, 101, 98, 32, 97, 112, 112, 108, 105, 99, 97,
|
||||
116, 105, 111, 110, 115, 44, 32, 115, 117, 99, 104, 32, 97,
|
||||
115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, 115,
|
||||
105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110,
|
||||
101, 114, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32,
|
||||
118, 101, 114, 105, 102, 105, 99, 97, 116, 105, 111, 110,
|
||||
44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, 112,
|
||||
116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99,
|
||||
114, 121, 112, 116, 105, 111, 110, 46, 32, 65, 100, 100,
|
||||
105, 116, 105, 111, 110, 97, 108, 108, 121, 44, 32, 105,
|
||||
116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97,
|
||||
110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112,
|
||||
108, 105, 99, 97, 116, 105, 111, 110, 115, 32, 116, 111,
|
||||
32, 103, 101, 110, 101, 114, 97, 116, 101, 32, 97, 110,
|
||||
100, 47, 111, 114, 32, 109, 97, 110, 97, 103, 101, 32, 116,
|
||||
104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97,
|
||||
116, 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115,
|
||||
115, 97, 114, 121, 32, 116, 111, 32, 112, 101, 114, 102,
|
||||
111, 114, 109, 32, 116, 104, 101, 115, 101, 32, 111, 112,
|
||||
101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115,
|
||||
101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32,
|
||||
65, 80, 73, 32, 114, 97, 110, 103, 101, 32, 102, 114, 111,
|
||||
109, 32, 117, 115, 101, 114, 32, 111, 114, 32, 115, 101,
|
||||
114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, 110,
|
||||
116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111,
|
||||
99, 117, 109, 101, 110, 116, 32, 111, 114, 32, 99, 111,
|
||||
100, 101, 32, 115, 105, 103, 110, 105, 110, 103, 44, 32,
|
||||
97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, 102,
|
||||
105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32,
|
||||
97, 110, 100, 32, 105, 110, 116, 101, 103, 114, 105, 116,
|
||||
121, 32, 111, 102, 32, 99, 111, 109, 109, 117, 110, 105,
|
||||
99, 97, 116, 105, 111, 110, 115, 46]);
|
||||
|
||||
// We want some random key bytes of various sizes.
|
||||
// These were randomly generated from a script.
|
||||
var keyBytes = {
|
||||
128: new Uint8Array([222, 192, 212, 252, 191, 60, 71,
|
||||
65, 200, 146, 218, 189, 28, 212, 192, 78]),
|
||||
192: new Uint8Array([208, 238, 131, 65, 63, 68, 196, 63, 186, 208,
|
||||
61, 207, 166, 18, 99, 152, 29, 109, 221, 95, 240, 30, 28, 246]),
|
||||
256: new Uint8Array([103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236,
|
||||
233, 204, 58, 249, 16, 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116,
|
||||
216, 0, 11, 191, 48])
|
||||
}
|
||||
|
||||
// AES-CBC needs a 16 byte (128 bit) IV.
|
||||
var iv = new Uint8Array([85, 170, 248, 155, 168, 148, 19, 213, 78, 167, 39,
|
||||
167, 108, 39, 162, 132]);
|
||||
|
||||
|
||||
// Results. These were created using the Python cryptography module.
|
||||
|
||||
// AES-CBC produces ciphertext
|
||||
var ciphertext = {
|
||||
128: new Uint8Array([35, 127, 3, 254, 231, 8, 114, 231, 143, 174, 193,
|
||||
72, 221, 189, 1, 189, 119, 203, 150, 227, 56, 30, 244, 236, 226, 175,
|
||||
234, 23, 167, 175, 211, 124, 203, 228, 97, 223, 156, 77, 88, 174,
|
||||
166, 187, 186, 225, 176, 92, 250, 177, 225, 41, 135, 124, 215, 86,
|
||||
198, 134, 124, 49, 154, 60, 224, 93, 165, 12, 190, 245, 241, 164,
|
||||
247, 220, 227, 69, 242, 105, 208, 108, 222, 193, 223, 0, 226, 217,
|
||||
39, 160, 78, 147, 191, 38, 153, 232, 206, 221, 254, 25, 185, 249, 7,
|
||||
181, 215, 104, 98, 163, 194, 161, 103, 161, 237, 167, 10, 242, 37,
|
||||
80, 2, 255, 173, 96, 20, 106, 170, 110, 80, 38, 136, 127, 16, 85,
|
||||
244, 78, 172, 56, 106, 3, 115, 130, 58, 186, 129, 236, 255, 251,
|
||||
178, 112, 24, 159, 82, 252, 1, 178, 132, 92, 40, 125, 18, 135, 116,
|
||||
64, 178, 31, 174, 87, 114, 114, 218, 78, 111, 0, 239, 252, 79, 63,
|
||||
119, 58, 118, 78, 55, 249, 36, 130, 225, 205, 13, 76, 97, 214, 250,
|
||||
174, 232, 67, 103, 211, 178, 206, 32, 129, 188, 243, 100, 71, 63,
|
||||
154, 159, 200, 125, 34, 138, 39, 73, 130, 75, 97, 203, 204, 111,
|
||||
244, 75, 186, 181, 43, 207, 175, 146, 98, 207, 27, 23, 90, 144, 161,
|
||||
19, 235, 199, 93, 98, 238, 72, 134, 157, 220, 207, 66, 167, 236, 94,
|
||||
57, 0, 3, 202, 250, 55, 26, 163, 20, 133, 191, 67, 20, 63, 150, 203,
|
||||
87, 216, 44, 57, 188, 236, 64, 80, 111, 68, 26, 12, 10, 163, 82, 3,
|
||||
191, 19, 71, 186, 196, 177, 84, 244, 7, 78, 41, 172, 203, 27, 225,
|
||||
231, 108, 206, 141, 221, 253, 204, 220, 134, 20, 130, 54, 113, 81,
|
||||
127, 197, 27, 101, 121, 159, 223, 193, 115, 190, 12, 153, 174, 231,
|
||||
196, 92, 142, 156, 61, 189, 3, 18, 153, 206, 190, 58, 255, 154, 115,
|
||||
66, 23, 107, 94, 220, 156, 220, 228, 241, 66, 6, 184, 44, 238, 249,
|
||||
51, 240, 109, 142, 208, 189, 11, 117, 70, 170, 217, 170, 216, 66,
|
||||
231, 18, 175, 121, 221, 16, 29, 139, 55, 103, 91, 239, 111, 29, 108,
|
||||
94, 179, 138, 134, 73, 130, 29, 69, 182, 192, 249, 150, 165, 79, 47,
|
||||
91, 203, 226, 63, 87, 52, 60, 172, 191, 190, 179, 171, 155, 205, 88,
|
||||
172, 111, 59, 40, 198, 250, 209, 148, 177, 115, 200, 40, 43, 165,
|
||||
167, 67, 116, 64, 159, 240, 81, 253, 235, 137, 132, 49, 223, 214,
|
||||
172, 53, 7, 47, 184, 223, 120, 59, 51, 33, 124, 147, 221, 27, 60,
|
||||
16, 254, 24, 115, 115, 214, 75, 73, 97, 136, 214, 209, 177, 106, 71,
|
||||
254, 211, 94, 57, 104, 170, 168, 35, 37, 93, 203, 199, 38, 28, 84]),
|
||||
|
||||
192: new Uint8Array([131, 160, 2, 14, 214, 229, 41, 230, 47, 99, 83,
|
||||
193, 62, 133, 172, 195, 127, 61, 247, 80, 71, 167, 37, 184, 230,
|
||||
207, 168, 163, 139, 145, 18, 225, 205, 134, 87, 138, 80, 247, 166,
|
||||
176, 177, 18, 71, 88, 193, 56, 45, 96, 36, 78, 134, 212, 9, 250, 217,
|
||||
24, 207, 215, 111, 72, 114, 203, 27, 188, 122, 34, 212, 191, 88, 72,
|
||||
22, 194, 224, 217, 236, 201, 191, 236, 214, 231, 90, 244, 100, 153,
|
||||
211, 35, 182, 205, 128, 84, 79, 161, 53, 166, 236, 196, 181, 163,
|
||||
140, 255, 80, 59, 49, 71, 170, 118, 14, 100, 40, 105, 184, 187, 41,
|
||||
198, 180, 135, 69, 211, 69, 74, 132, 243, 76, 144, 102, 90, 155,
|
||||
243, 125, 140, 190, 20, 9, 232, 188, 198, 221, 148, 13, 53, 155, 91,
|
||||
34, 235, 24, 121, 109, 48, 242, 142, 8, 160, 223, 242, 163, 98, 198,
|
||||
131, 164, 160, 79, 27, 210, 216, 192, 228, 27, 4, 254, 222, 195, 14,
|
||||
77, 72, 225, 151, 114, 38, 130, 143, 6, 17, 138, 229, 193, 114, 169,
|
||||
2, 108, 225, 35, 37, 232, 200, 167, 147, 251, 210, 138, 243, 44, 48,
|
||||
12, 84, 192, 169, 108, 0, 113, 77, 160, 218, 96, 4, 138, 171, 207,
|
||||
20, 189, 146, 255, 206, 68, 160, 87, 127, 3, 83, 182, 203, 116, 59,
|
||||
24, 186, 79, 68, 220, 161, 85, 227, 29, 118, 134, 128, 187, 29, 128,
|
||||
121, 120, 64, 211, 30, 255, 52, 187, 185, 216, 151, 30, 10, 165,
|
||||
203, 148, 39, 224, 14, 173, 199, 57, 0, 194, 79, 115, 206, 159, 43,
|
||||
13, 36, 169, 97, 144, 32, 0, 207, 230, 16, 162, 156, 166, 34, 150,
|
||||
12, 93, 141, 164, 181, 194, 10, 47, 139, 82, 75, 42, 23, 224, 3, 92,
|
||||
151, 154, 249, 170, 57, 141, 113, 32, 52, 158, 218, 49, 242, 134,
|
||||
65, 69, 203, 71, 19, 133, 125, 117, 1, 207, 210, 224, 130, 45, 37,
|
||||
42, 181, 139, 34, 85, 8, 67, 165, 249, 180, 89, 3, 60, 152, 1, 231,
|
||||
49, 1, 124, 243, 81, 44, 72, 232, 239, 129, 75, 108, 4, 169, 132,
|
||||
73, 183, 21, 29, 46, 94, 138, 83, 190, 131, 146, 65, 104, 107, 251,
|
||||
218, 95, 227, 94, 145, 70, 0, 2, 252, 59, 188, 58, 150, 203, 148,
|
||||
100, 219, 36, 182, 81, 237, 138, 160, 83, 151, 119, 11, 216, 122,
|
||||
134, 189, 246, 251, 192, 41, 158, 125, 247, 190, 32, 173, 104, 9,
|
||||
58, 223, 97, 212, 48, 62, 3, 112, 21, 74, 206, 87, 182, 110, 197,
|
||||
67, 68, 155, 189, 223, 136, 2, 239, 137, 151, 138, 252, 162, 141,
|
||||
255, 209, 25, 4, 146, 24, 221, 43, 148, 120, 26, 228, 208, 200, 198,
|
||||
192, 4, 96, 70, 227, 237, 104, 17, 67, 9, 211]),
|
||||
|
||||
256: new Uint8Array([41, 213, 121, 140, 181, 227, 200, 97, 100, 133, 58,
|
||||
227, 106, 115, 25, 63, 77, 51, 26, 57, 238, 140, 99, 63, 71, 211,
|
||||
128, 84, 115, 26, 236, 52, 103, 81, 145, 14, 101, 161, 181, 58, 135,
|
||||
193, 56, 167, 214, 220, 5, 52, 85, 222, 183, 27, 101, 134, 86, 155,
|
||||
64, 148, 124, 212, 219, 251, 65, 42, 32, 44, 128, 2, 50, 128, 221,
|
||||
22, 238, 56, 189, 83, 28, 122, 121, 157, 215, 135, 151, 128, 233,
|
||||
193, 65, 190, 86, 148, 191, 140, 196, 120, 8, 172, 100, 166, 254,
|
||||
41, 245, 75, 56, 6, 166, 244, 178, 111, 234, 23, 4, 107, 6, 22, 132,
|
||||
187, 230, 17, 71, 172, 113, 238, 73, 4, 180, 90, 103, 77, 37, 51,
|
||||
118, 112, 129, 238, 199, 7, 222, 122, 173, 30, 232, 178, 233, 234,
|
||||
144, 98, 14, 234, 112, 77, 68, 62, 62, 159, 230, 101, 98, 43, 2,
|
||||
204, 69, 156, 86, 104, 128, 34, 128, 7, 173, 90, 120, 33, 104, 59,
|
||||
45, 251, 93, 51, 240, 232, 60, 94, 189, 134, 90, 20, 184, 122, 29,
|
||||
225, 85, 213, 38, 116, 159, 80, 69, 106, 168, 236, 201, 69, 140, 98,
|
||||
240, 45, 160, 133, 225, 106, 45, 245, 212, 160, 176, 128, 27, 114,
|
||||
153, 182, 144, 145, 214, 72, 196, 138, 183, 87, 61, 245, 150, 56,
|
||||
82, 158, 224, 50, 114, 125, 122, 172, 161, 129, 234, 70, 63, 245,
|
||||
136, 30, 136, 9, 128, 220, 229, 157, 222, 195, 149, 189, 70, 8, 71,
|
||||
40, 195, 93, 27, 7, 234, 164, 175, 102, 201, 149, 115, 248, 179,
|
||||
125, 66, 122, 194, 26, 61, 218, 198, 181, 152, 140, 199, 48, 148,
|
||||
31, 14, 241, 197, 3, 70, 128, 239, 32, 86, 15, 215, 86, 245, 190,
|
||||
95, 141, 41, 111, 0, 232, 28, 152, 67, 87, 197, 255, 118, 13, 251,
|
||||
71, 84, 22, 231, 134, 188, 175, 115, 138, 37, 199, 5, 238, 199, 2,
|
||||
99, 203, 75, 62, 231, 21, 150, 239, 94, 201, 185, 219, 58, 210, 228,
|
||||
151, 131, 76, 148, 104, 60, 74, 82, 6, 168, 49, 251, 182, 3, 232,
|
||||
173, 210, 201, 19, 101, 166, 7, 94, 11, 194, 211, 146, 229, 75, 241,
|
||||
15, 50, 187, 36, 175, 78, 227, 98, 224, 3, 95, 209, 93, 126, 112,
|
||||
178, 29, 18, 108, 241, 232, 79, 210, 41, 2, 238, 208, 190, 171, 134,
|
||||
147, 188, 191, 229, 122, 32, 209, 166, 118, 129, 223, 130, 214, 195,
|
||||
89, 67, 94, 218, 155, 185, 0, 144, 255, 132, 213, 25, 59, 83, 242,
|
||||
57, 69, 148, 109, 133, 61, 163, 30, 214, 254, 54, 169, 3, 217, 77,
|
||||
66, 123, 193, 204, 199, 109, 123, 49, 186, 223, 229, 8, 230, 164,
|
||||
171, 196, 145, 225, 10, 111, 248, 111, 164, 216, 54, 225, 253])
|
||||
};
|
||||
|
||||
// Replace the last block of each ciphertext with bad padding below for decryption errors
|
||||
var badPadding = {
|
||||
128: {
|
||||
"zeroPadChar": new Uint8Array([238, 27, 248, 169, 218, 138, 164, 86, 207, 102, 36, 223, 6, 166, 77, 14]),
|
||||
"bigPadChar": new Uint8Array([91, 67, 119, 104, 252, 238, 175, 144, 17, 75, 12, 163, 212, 52, 46, 51]),
|
||||
"inconsistentPadChars": new Uint8Array([135, 101, 112, 208, 3, 106, 226, 20, 25, 219, 79, 94, 58, 212, 242, 192])
|
||||
},
|
||||
192: {
|
||||
"zeroPadChar": new Uint8Array([22, 158, 50, 15, 168, 47, 19, 194, 182, 133, 184, 65, 36, 43, 177, 254]),
|
||||
"bigPadChar": new Uint8Array([207, 110, 28, 160, 165, 213, 48, 213, 163, 242, 15, 78, 96, 117, 106, 87]),
|
||||
"inconsistentPadChars": new Uint8Array([143, 227, 12, 112, 216, 207, 136, 167, 78, 137, 93, 30, 50, 75, 102, 101])
|
||||
},
|
||||
256: {
|
||||
"zeroPadChar": new Uint8Array([1, 253, 141, 214, 30, 193, 254, 68, 140, 200, 157, 110, 200, 89, 177, 129]),
|
||||
"bigPadChar": new Uint8Array([88, 7, 110, 221, 74, 34, 97, 109, 99, 25, 189, 222, 94, 90, 27, 60]),
|
||||
"inconsistentPadChars": new Uint8Array([152, 54, 60, 148, 59, 136, 193, 21, 77, 140, 170, 67, 120, 74, 106, 62])
|
||||
}
|
||||
};
|
||||
|
||||
var keyLengths = [128, 192, 256];
|
||||
|
||||
// All the scenarios that should succeed, if the key has "encrypt" usage
|
||||
var passing = [];
|
||||
keyLengths.forEach(function(keyLength) {
|
||||
passing.push({
|
||||
name: "AES-CBC " + keyLength.toString() + "-bit key",
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-CBC", iv: iv},
|
||||
plaintext: plaintext,
|
||||
result: ciphertext[keyLength]
|
||||
});
|
||||
});
|
||||
|
||||
// Scenarios that should fail because of a bad iv length, causing an OperationError
|
||||
var failing = [];
|
||||
keyLengths.forEach(function(keyLength) {
|
||||
var shortIv = iv.slice(0, 8);
|
||||
failing.push({
|
||||
name: "AES-CBC " + keyLength.toString() + "-bit key, 64-bit IV",
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-CBC", iv: shortIv},
|
||||
plaintext: plaintext,
|
||||
result: ciphertext[keyLength]
|
||||
});
|
||||
|
||||
var longIv = new Uint8Array(24);
|
||||
longIv.set(iv, 0);
|
||||
longIv.set(iv.slice(0, 8), 16);
|
||||
failing.push({
|
||||
name: "AES-CBC " + keyLength.toString() + "-bit key, 192-bit IV",
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-CBC", iv: longIv},
|
||||
plaintext: plaintext,
|
||||
result: ciphertext[keyLength]
|
||||
});
|
||||
});
|
||||
|
||||
// Scenarios that should fail decryption because of bad padding
|
||||
var decryptionFailing = [];
|
||||
keyLengths.forEach(function(keyLength) {
|
||||
["zeroPadChar", "bigPadChar", "inconsistentPadChars"].forEach(function(paddingProblem) {
|
||||
var badCiphertext = new Uint8Array(ciphertext[keyLength].byteLength);
|
||||
badCiphertext.set(ciphertext[keyLength].slice(0, ciphertext[keyLength].byteLength - 16));
|
||||
badCiphertext.set(badPadding[keyLength][paddingProblem]);
|
||||
|
||||
decryptionFailing.push({
|
||||
name: "AES-CBC " + keyLength.toString() + "-bit key, " + paddingProblem,
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-CBC", iv: iv},
|
||||
plaintext: plaintext,
|
||||
result: badCiphertext
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return {passing: passing, failing: failing, decryptionFailing: decryptionFailing};
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("aes_ctr_vectors.js");
|
||||
importScripts("aes.js");
|
||||
|
||||
run_test();
|
|
@ -0,0 +1,123 @@
|
|||
|
||||
// aes_ctr_vectors.js
|
||||
|
||||
// The following function returns an array of test vectors
|
||||
// for the subtleCrypto encrypt method.
|
||||
//
|
||||
// Each test vector has the following fields:
|
||||
// name - a unique name for this vector
|
||||
// keyBuffer - an arrayBuffer with the key data in raw form
|
||||
// key - a CryptoKey object for the keyBuffer. INITIALLY null! You must fill this in first to use it!
|
||||
// algorithm - the value of the AlgorithmIdentifier parameter to provide to encrypt
|
||||
// plaintext - the text to encrypt
|
||||
// result - the expected result (usually just ciphertext, sometimes with added authentication)
|
||||
function getTestVectors() {
|
||||
// Before we can really start, we need to fill a bunch of buffers with data
|
||||
var plaintext = new Uint8Array([84, 104, 105, 115, 32, 115,
|
||||
112, 101, 99, 105, 102, 105, 99, 97, 116, 105, 111, 110,
|
||||
32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32,
|
||||
74, 97, 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80,
|
||||
73, 32, 102, 111, 114, 32, 112, 101, 114, 102, 111, 114,
|
||||
109, 105, 110, 103, 32, 98, 97, 115, 105, 99, 32, 99, 114,
|
||||
121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32,
|
||||
111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105,
|
||||
110, 32, 119, 101, 98, 32, 97, 112, 112, 108, 105, 99, 97,
|
||||
116, 105, 111, 110, 115, 44, 32, 115, 117, 99, 104, 32, 97,
|
||||
115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, 115,
|
||||
105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110,
|
||||
101, 114, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32,
|
||||
118, 101, 114, 105, 102, 105, 99, 97, 116, 105, 111, 110,
|
||||
44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, 112,
|
||||
116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99,
|
||||
114, 121, 112, 116, 105, 111, 110, 46, 32, 65, 100, 100,
|
||||
105, 116, 105, 111, 110, 97, 108, 108, 121, 44, 32, 105,
|
||||
116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97,
|
||||
110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112,
|
||||
108, 105, 99, 97, 116, 105, 111, 110, 115, 32, 116, 111,
|
||||
32, 103, 101, 110, 101, 114, 97, 116, 101, 32, 97, 110,
|
||||
100, 47, 111, 114, 32, 109, 97, 110, 97, 103, 101, 32, 116,
|
||||
104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97,
|
||||
116, 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115,
|
||||
115, 97, 114, 121, 32, 116, 111, 32, 112, 101, 114, 102,
|
||||
111, 114, 109, 32, 116, 104, 101, 115, 101, 32, 111, 112,
|
||||
101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115,
|
||||
101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32,
|
||||
65, 80, 73, 32, 114, 97, 110, 103, 101, 32, 102, 114, 111,
|
||||
109, 32, 117, 115, 101, 114, 32, 111, 114, 32, 115, 101,
|
||||
114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, 110,
|
||||
116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111,
|
||||
99, 117, 109, 101, 110, 116, 32, 111, 114, 32, 99, 111,
|
||||
100, 101, 32, 115, 105, 103, 110, 105, 110, 103, 44, 32,
|
||||
97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, 102,
|
||||
105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32,
|
||||
97, 110, 100, 32, 105, 110, 116, 101, 103, 114, 105, 116,
|
||||
121, 32, 111, 102, 32, 99, 111, 109, 109, 117, 110, 105,
|
||||
99, 97, 116, 105, 111, 110, 115, 46]);
|
||||
|
||||
// We want some random key bytes of various sizes.
|
||||
// These were randomly generated from a script.
|
||||
var keyBytes = {
|
||||
128: new Uint8Array([222, 192, 212, 252, 191, 60, 71,
|
||||
65, 200, 146, 218, 189, 28, 212, 192, 78]),
|
||||
192: new Uint8Array([208, 238, 131, 65, 63, 68, 196, 63, 186, 208,
|
||||
61, 207, 166, 18, 99, 152, 29, 109, 221, 95, 240, 30, 28, 246]),
|
||||
256: new Uint8Array([103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236,
|
||||
233, 204, 58, 249, 16, 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116,
|
||||
216, 0, 11, 191, 48])
|
||||
}
|
||||
|
||||
// AES-CTR needs a 16 byte (128 bit) counter.
|
||||
var counter = new Uint8Array([85, 170, 248, 155, 168, 148, 19, 213, 78, 167, 39,
|
||||
167, 108, 39, 162, 132]);
|
||||
|
||||
|
||||
// Results. These were created using the Python cryptography module.
|
||||
|
||||
// AES-CTR produces ciphertext
|
||||
var ciphertext = {
|
||||
128: new Uint8Array([233, 17, 117, 253, 164, 245, 234, 87, 197, 43, 13, 0, 11, 190, 152, 175, 104, 192, 165, 144, 88, 174, 237, 138, 181, 183, 6, 53, 3, 161, 206, 71, 13, 121, 218, 209, 116, 249, 10, 170, 250, 165, 68, 157, 132, 141, 200, 178, 197, 87, 209, 231, 250, 75, 154, 65, 162, 251, 30, 159, 234, 20, 20, 181, 147, 218, 180, 12, 4, 241, 75, 79, 129, 64, 15, 228, 60, 147, 153, 1, 129, 176, 150, 161, 85, 97, 22, 154, 234, 23, 127, 16, 4, 22, 226, 11, 104, 16, 176, 14, 225, 176, 79, 239, 103, 243, 190, 222, 40, 186, 244, 212, 29, 57, 125, 175, 21, 17, 233, 2, 13, 119, 102, 233, 230, 4, 16, 222, 56, 225, 67, 45, 191, 250, 15, 153, 45, 193, 240, 212, 117, 101, 68, 232, 199, 101, 175, 125, 247, 6, 249, 14, 0, 157, 185, 56, 76, 51, 228, 77, 234, 84, 60, 42, 119, 187, 213, 32, 34, 222, 65, 231, 215, 26, 73, 141, 231, 254, 185, 118, 14, 180, 126, 80, 51, 102, 200, 141, 204, 45, 26, 56, 119, 136, 222, 45, 143, 120, 231, 44, 43, 221, 136, 21, 188, 138, 84, 232, 208, 238, 226, 117, 104, 60, 165, 4, 18, 144, 240, 49, 173, 90, 68, 84, 239, 161, 124, 196, 144, 119, 24, 243, 239, 75, 117, 254, 219, 209, 53, 131, 37, 79, 68, 26, 21, 168, 163, 50, 59, 18, 244, 11, 143, 190, 188, 129, 108, 249, 180, 104, 216, 215, 165, 160, 251, 84, 132, 152, 195, 154, 110, 216, 70, 21, 248, 148, 146, 152, 56, 174, 248, 227, 1, 102, 15, 118, 182, 50, 73, 63, 35, 112, 159, 237, 253, 94, 16, 127, 120, 38, 127, 51, 27, 96, 163, 140, 20, 111, 151, 16, 72, 74, 74, 205, 239, 241, 16, 179, 183, 116, 95, 248, 58, 168, 203, 93, 233, 225, 91, 17, 226, 10, 120, 85, 114, 4, 31, 40, 82, 161, 152, 17, 86, 237, 207, 7, 228, 110, 182, 65, 68, 68, 156, 206, 116, 185, 204, 148, 22, 58, 111, 218, 138, 225, 146, 25, 114, 29, 96, 183, 87, 181, 181, 236, 113, 141, 171, 213, 9, 84, 182, 230, 163, 147, 246, 86, 246, 52, 111, 64, 34, 157, 12, 80, 224, 28, 21, 112, 31, 42, 79, 229, 210, 90, 23, 78, 223, 155, 144, 238, 12, 14, 191, 158, 6, 181, 254, 0, 85, 134, 56, 161, 234, 55, 129, 64, 59, 12, 146, 6, 217, 232, 20, 214, 167, 159, 183, 165, 96, 96, 225, 199, 23, 106, 243, 108, 106, 26, 214, 53, 152, 26, 155, 253, 128, 7, 216, 207, 109, 159, 147, 240, 232, 226, 43, 147, 169, 162, 204, 215, 9, 10, 177, 223, 99, 206, 163, 240, 64]),
|
||||
|
||||
192: new Uint8Array([98, 123, 235, 65, 14, 86, 80, 133, 88, 104, 244, 125, 165, 185, 163, 4, 3, 230, 62, 58, 113, 222, 46, 210, 17, 155, 95, 19, 125, 125, 70, 234, 105, 54, 23, 246, 114, 9, 237, 191, 9, 194, 34, 254, 156, 11, 50, 216, 80, 178, 185, 221, 132, 154, 27, 85, 82, 49, 241, 123, 23, 106, 119, 134, 203, 0, 151, 66, 149, 218, 124, 247, 227, 233, 236, 184, 88, 234, 174, 250, 83, 168, 33, 15, 122, 26, 96, 213, 210, 4, 52, 92, 20, 12, 64, 12, 209, 197, 69, 100, 15, 56, 60, 63, 241, 52, 18, 189, 93, 146, 47, 60, 33, 200, 218, 243, 43, 169, 17, 108, 19, 199, 174, 33, 107, 186, 57, 95, 167, 138, 180, 187, 53, 113, 208, 148, 190, 48, 167, 53, 209, 52, 153, 184, 231, 63, 168, 54, 179, 238, 93, 130, 125, 3, 149, 119, 60, 25, 142, 150, 183, 193, 29, 18, 3, 219, 235, 219, 26, 116, 217, 196, 108, 6, 96, 103, 212, 48, 227, 91, 124, 77, 181, 169, 18, 111, 123, 83, 26, 169, 230, 88, 103, 185, 153, 93, 143, 152, 142, 231, 41, 226, 226, 156, 179, 206, 212, 67, 18, 193, 187, 53, 252, 214, 15, 228, 246, 131, 170, 101, 134, 212, 100, 170, 146, 47, 57, 125, 50, 230, 51, 246, 74, 175, 129, 196, 178, 206, 176, 52, 153, 39, 77, 24, 186, 99, 137, 83, 105, 111, 168, 35, 176, 24, 29, 170, 223, 74, 160, 138, 247, 12, 102, 233, 136, 59, 172, 228, 242, 84, 13, 34, 155, 80, 80, 87, 180, 143, 129, 61, 213, 54, 41, 8, 183, 102, 126, 179, 127, 77, 55, 176, 152, 41, 131, 85, 86, 225, 87, 216, 139, 226, 196, 195, 210, 34, 33, 161, 249, 153, 205, 197, 128, 41, 28, 121, 6, 159, 25, 211, 168, 137, 26, 217, 249, 113, 81, 141, 18, 1, 250, 228, 68, 238, 74, 54, 99, 167, 236, 176, 199, 148, 161, 143, 156, 51, 189, 204, 59, 240, 151, 170, 85, 63, 23, 38, 152, 199, 12, 81, 217, 244, 178, 231, 249, 159, 224, 107, 214, 58, 127, 116, 143, 219, 155, 80, 55, 213, 171, 80, 127, 235, 20, 247, 12, 104, 228, 147, 202, 124, 143, 110, 223, 76, 221, 154, 175, 143, 185, 237, 222, 189, 104, 218, 72, 244, 55, 253, 138, 183, 92, 231, 68, 176, 239, 171, 100, 10, 63, 61, 194, 228, 15, 133, 216, 45, 60, 135, 203, 142, 127, 153, 172, 223, 213, 230, 220, 189, 223, 234, 156, 134, 238, 220, 251, 104, 209, 117, 175, 47, 46, 148, 6, 61, 216, 215, 39, 30, 116, 212, 45, 112, 202, 227, 198, 98, 253, 97, 177, 120, 74, 238, 68, 99, 240, 96, 43, 88, 166]),
|
||||
|
||||
256: new Uint8Array([55, 82, 154, 67, 47, 80, 186, 78, 83, 56, 95, 130, 102, 236, 61, 236, 204, 236, 234, 222, 122, 226, 147, 149, 233, 41, 16, 118, 201, 91, 185, 162, 79, 71, 146, 252, 221, 110, 165, 137, 75, 129, 94, 219, 93, 94, 64, 34, 250, 190, 5, 90, 6, 177, 167, 224, 25, 121, 85, 91, 87, 152, 56, 100, 191, 35, 1, 156, 177, 179, 127, 253, 173, 176, 87, 247, 40, 207, 178, 175, 10, 51, 209, 70, 52, 76, 251, 160, 172, 203, 77, 191, 97, 58, 123, 238, 82, 60, 166, 214, 134, 14, 71, 74, 156, 15, 77, 6, 141, 76, 10, 205, 148, 204, 85, 203, 242, 30, 66, 133, 202, 21, 17, 108, 151, 2, 15, 44, 51, 180, 88, 80, 8, 248, 254, 151, 201, 226, 156, 6, 39, 197, 212, 124, 72, 217, 75, 232, 139, 155, 22, 199, 242, 223, 116, 10, 141, 42, 7, 85, 99, 5, 184, 43, 145, 159, 122, 135, 202, 46, 209, 157, 178, 114, 98, 194, 119, 194, 19, 242, 167, 236, 162, 94, 90, 106, 219, 234, 67, 11, 162, 225, 6, 17, 152, 23, 16, 84, 40, 90, 255, 158, 8, 105, 198, 56, 220, 213, 36, 203, 241, 242, 85, 218, 103, 90, 202, 214, 215, 134, 121, 169, 149, 139, 122, 143, 155, 178, 29, 217, 197, 128, 173, 25, 111, 154, 14, 76, 106, 101, 0, 215, 187, 33, 223, 116, 205, 89, 52, 206, 60, 77, 141, 31, 57, 211, 74, 42, 219, 88, 210, 36, 196, 128, 151, 136, 124, 222, 157, 59, 225, 70, 163, 234, 59, 173, 228, 198, 134, 76, 249, 228, 69, 181, 196, 194, 179, 239, 78, 43, 143, 94, 234, 10, 177, 192, 185, 171, 231, 164, 254, 91, 44, 11, 29, 148, 223, 107, 18, 149, 61, 50, 115, 38, 14, 128, 189, 9, 77, 236, 151, 163, 23, 122, 156, 236, 11, 80, 66, 190, 24, 4, 4, 12, 148, 57, 64, 59, 143, 114, 247, 66, 111, 167, 86, 173, 98, 102, 207, 44, 134, 89, 231, 64, 50, 157, 208, 210, 79, 159, 133, 73, 118, 98, 202, 215, 57, 247, 29, 97, 116, 1, 28, 119, 248, 243, 31, 180, 66, 38, 40, 141, 251, 134, 129, 126, 241, 113, 22, 50, 28, 113, 187, 158, 217, 125, 182, 233, 144, 246, 32, 88, 88, 15, 0, 102, 131, 67, 31, 34, 150, 98, 241, 213, 227, 205, 175, 254, 3, 53, 70, 124, 167, 38, 53, 104, 140, 147, 158, 200, 179, 45, 100, 101, 246, 81, 166, 53, 247, 60, 10, 78, 127, 10, 173, 176, 232, 31, 91, 203, 250, 236, 38, 113, 172, 151, 253, 194, 253, 50, 242, 76, 148, 23, 117, 195, 122, 104, 16, 212, 177, 113, 188, 138, 186, 144, 168, 102, 3])
|
||||
};
|
||||
|
||||
var keyLengths = [128, 192, 256];
|
||||
|
||||
// All the scenarios that should succeed, if the key has "encrypt" usage
|
||||
var passing = [];
|
||||
keyLengths.forEach(function(keyLength) {
|
||||
passing.push({
|
||||
name: "AES-CTR " + keyLength.toString() + "-bit key",
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-CTR", counter: counter, length: 64},
|
||||
plaintext: plaintext,
|
||||
result: ciphertext[keyLength]
|
||||
});
|
||||
});
|
||||
|
||||
// Scenarios that should fail because of a bad length parameter, causing an OperationError
|
||||
var failing = [];
|
||||
keyLengths.forEach(function(keyLength) {
|
||||
failing.push({
|
||||
name: "AES-CTR " + keyLength.toString() + "-bit key, 0-bit counter",
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-CTR", counter: counter, length: 0},
|
||||
plaintext: plaintext,
|
||||
result: ciphertext[keyLength]
|
||||
});
|
||||
|
||||
failing.push({
|
||||
name: "AES-CTR " + keyLength.toString() + "-bit key, 129-bit counter",
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-CTR", counter: counter, length: 129},
|
||||
plaintext: plaintext,
|
||||
result: ciphertext[keyLength]
|
||||
});
|
||||
});
|
||||
|
||||
return {passing: passing, failing: failing, decryptionFailing: []};
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("aes_gcm_vectors.js");
|
||||
importScripts("aes.js");
|
||||
|
||||
run_test();
|
|
@ -0,0 +1,262 @@
|
|||
|
||||
// aes_gcm_vectors.js
|
||||
|
||||
// The following function returns an array of test vectors
|
||||
// for the subtleCrypto encrypt method.
|
||||
//
|
||||
// Each test vector has the following fields:
|
||||
// name - a unique name for this vector
|
||||
// keyBuffer - an arrayBuffer with the key data in raw form
|
||||
// key - a CryptoKey object for the keyBuffer. INITIALLY null! You must fill this in first to use it!
|
||||
// algorithm - the value of the AlgorithmIdentifier parameter to provide to encrypt
|
||||
// plaintext - the text to encrypt
|
||||
// result - the expected result (usually just ciphertext, sometimes with added authentication)
|
||||
function getTestVectors() {
|
||||
// Before we can really start, we need to fill a bunch of buffers with data
|
||||
var plaintext = new Uint8Array([84, 104, 105, 115, 32, 115,
|
||||
112, 101, 99, 105, 102, 105, 99, 97, 116, 105, 111, 110,
|
||||
32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32,
|
||||
74, 97, 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80,
|
||||
73, 32, 102, 111, 114, 32, 112, 101, 114, 102, 111, 114,
|
||||
109, 105, 110, 103, 32, 98, 97, 115, 105, 99, 32, 99, 114,
|
||||
121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32,
|
||||
111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105,
|
||||
110, 32, 119, 101, 98, 32, 97, 112, 112, 108, 105, 99, 97,
|
||||
116, 105, 111, 110, 115, 44, 32, 115, 117, 99, 104, 32, 97,
|
||||
115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, 115,
|
||||
105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110,
|
||||
101, 114, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32,
|
||||
118, 101, 114, 105, 102, 105, 99, 97, 116, 105, 111, 110,
|
||||
44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, 112,
|
||||
116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99,
|
||||
114, 121, 112, 116, 105, 111, 110, 46, 32, 65, 100, 100,
|
||||
105, 116, 105, 111, 110, 97, 108, 108, 121, 44, 32, 105,
|
||||
116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97,
|
||||
110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112,
|
||||
108, 105, 99, 97, 116, 105, 111, 110, 115, 32, 116, 111,
|
||||
32, 103, 101, 110, 101, 114, 97, 116, 101, 32, 97, 110,
|
||||
100, 47, 111, 114, 32, 109, 97, 110, 97, 103, 101, 32, 116,
|
||||
104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97,
|
||||
116, 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115,
|
||||
115, 97, 114, 121, 32, 116, 111, 32, 112, 101, 114, 102,
|
||||
111, 114, 109, 32, 116, 104, 101, 115, 101, 32, 111, 112,
|
||||
101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115,
|
||||
101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32,
|
||||
65, 80, 73, 32, 114, 97, 110, 103, 101, 32, 102, 114, 111,
|
||||
109, 32, 117, 115, 101, 114, 32, 111, 114, 32, 115, 101,
|
||||
114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, 110,
|
||||
116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111,
|
||||
99, 117, 109, 101, 110, 116, 32, 111, 114, 32, 99, 111,
|
||||
100, 101, 32, 115, 105, 103, 110, 105, 110, 103, 44, 32,
|
||||
97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, 102,
|
||||
105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32,
|
||||
97, 110, 100, 32, 105, 110, 116, 101, 103, 114, 105, 116,
|
||||
121, 32, 111, 102, 32, 99, 111, 109, 109, 117, 110, 105,
|
||||
99, 97, 116, 105, 111, 110, 115, 46]);
|
||||
|
||||
// We want some random key bytes of various sizes.
|
||||
// These were randomly generated from a script.
|
||||
var keyBytes = {
|
||||
128: new Uint8Array([222, 192, 212, 252, 191, 60, 71,
|
||||
65, 200, 146, 218, 189, 28, 212, 192, 78]),
|
||||
192: new Uint8Array([208, 238, 131, 65, 63, 68, 196, 63, 186, 208,
|
||||
61, 207, 166, 18, 99, 152, 29, 109, 221, 95, 240, 30, 28, 246]),
|
||||
256: new Uint8Array([103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236,
|
||||
233, 204, 58, 249, 16, 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116,
|
||||
216, 0, 11, 191, 48])
|
||||
}
|
||||
|
||||
// AES-GCM needs an IV of no more than 2^64 - 1 bytes. Well, 32 bytes is okay then.
|
||||
var iv = new Uint8Array([58, 146, 115, 42, 166, 234, 57,
|
||||
191, 57, 134, 224, 199, 63, 169, 32, 0, 32, 33, 117, 56,
|
||||
94, 248, 173, 234, 194, 200, 115, 53, 235, 146, 141, 212]);
|
||||
|
||||
// Authenticated encryption via AES-GCM requires additional data that
|
||||
// will be checked. We use the ASCII encoded Editorial Note
|
||||
// following the Abstract of the Web Cryptography API recommendation.
|
||||
var additionalData = new Uint8Array([84, 104, 101, 114, 101,
|
||||
32, 97, 114, 101, 32, 55, 32, 102, 117, 114, 116, 104, 101,
|
||||
114, 32, 101, 100, 105, 116, 111, 114, 105, 97, 108, 32,
|
||||
110, 111, 116, 101, 115, 32, 105, 110, 32, 116, 104, 101,
|
||||
32, 100, 111, 99, 117, 109, 101, 110, 116, 46]);
|
||||
|
||||
// The length of the tag defaults to 16 bytes (128 bit).
|
||||
var tag = {
|
||||
128: new Uint8Array([194, 226, 198, 253, 239, 28,
|
||||
197, 240, 123, 216, 176, 151, 239, 200, 184, 183]),
|
||||
192: new Uint8Array([183, 57, 32, 144, 164, 76, 121, 77, 58,
|
||||
86, 62, 132, 53, 130, 96, 225]),
|
||||
256: new Uint8Array([188, 239, 241, 48, 159, 21, 213, 0, 241,
|
||||
42, 85, 76, 194, 28, 49, 60])
|
||||
};
|
||||
|
||||
var tag_with_empty_ad = {
|
||||
128: new Uint8Array([222, 51, 11, 23, 36, 222, 250, 248, 27, 98, 30, 81, 150, 35, 220, 198]),
|
||||
192: new Uint8Array([243, 11, 130, 112, 169, 239, 114, 238, 185, 219, 93, 1, 95, 108, 184, 183]),
|
||||
256: new Uint8Array([244, 186, 86, 203, 154, 37, 191, 248, 246, 57, 139, 130, 224, 47, 217, 238])
|
||||
};
|
||||
|
||||
|
||||
// Results. These were created using the Python cryptography module.
|
||||
|
||||
// AES-GCM produces ciphertext and a tag.
|
||||
var ciphertext = {
|
||||
128: new Uint8Array([180, 241, 40, 183, 105,
|
||||
52, 147, 238, 224, 175, 175, 236, 168, 244, 241, 121, 9,
|
||||
202, 225, 237, 56, 216, 253, 254, 186, 102, 111, 207, 228,
|
||||
190, 130, 177, 159, 246, 6, 53, 249, 113, 228, 254, 81,
|
||||
126, 253, 191, 100, 43, 251, 147, 107, 91, 166, 231, 201,
|
||||
241, 180, 214, 112, 47, 123, 164, 186, 134, 54, 65, 22,
|
||||
181, 201, 82, 236, 59, 52, 139, 172, 39, 41, 89, 123, 62,
|
||||
102, 167, 82, 150, 250, 93, 96, 169, 135, 89, 245, 255,
|
||||
164, 192, 169, 159, 25, 16, 139, 145, 76, 4, 144, 131,
|
||||
148, 197, 204, 46, 23, 110, 193, 228, 127, 120, 242, 24,
|
||||
54, 240, 181, 162, 98, 244, 249, 68, 134, 122, 126, 151,
|
||||
38, 108, 116, 68, 150, 109, 38, 194, 21, 159, 140, 205,
|
||||
183, 35, 97, 151, 186, 120, 145, 22, 235, 22, 210, 223,
|
||||
187, 143, 162, 183, 93, 196, 104, 51, 96, 53, 234, 250,
|
||||
184, 76, 237, 157, 37, 203, 226, 87, 222, 75, 240, 95, 218,
|
||||
222, 64, 81, 165, 75, 201, 216, 190, 13, 116, 217, 69, 66,
|
||||
47, 161, 68, 247, 74, 253, 157, 181, 162, 121, 53, 32, 91,
|
||||
124, 230, 105, 224, 17, 187, 50, 61, 77, 103, 79, 71, 57,
|
||||
163, 116, 234, 149, 27, 105, 24, 31, 159, 3, 128, 130, 42,
|
||||
94, 125, 200, 142, 251, 148, 201, 17, 149, 232, 84, 50, 17,
|
||||
18, 203, 186, 226, 164, 227, 202, 76, 65, 16, 163, 224,
|
||||
132, 52, 31, 101, 129, 72, 171, 159, 42, 177, 253, 98, 86,
|
||||
201, 95, 117, 62, 12, 205, 78, 36, 126, 196, 121, 89, 185,
|
||||
37, 161, 66, 181, 117, 186, 71, 124, 132, 110, 120, 27,
|
||||
246, 163, 18, 13, 90, 200, 127, 82, 209, 241, 170, 73, 247,
|
||||
137, 96, 244, 254, 251, 119, 71, 156, 27, 107, 53, 33, 45,
|
||||
22, 0, 144, 48, 32, 11, 116, 21, 125, 246, 217, 171, 158,
|
||||
224, 142, 234, 141, 242, 168, 89, 154, 66, 227, 161, 182,
|
||||
96, 1, 88, 78, 12, 7, 239, 30, 206, 31, 89, 111, 107, 42,
|
||||
37, 241, 148, 232, 1, 8, 251, 117, 146, 183, 9, 48, 39, 94,
|
||||
59, 70, 230, 26, 165, 97, 156, 140, 141, 31, 62, 10, 206,
|
||||
55, 48, 207, 0, 197, 202, 197, 108, 133, 175, 80, 4, 16,
|
||||
154, 223, 255, 4, 196, 188, 178, 240, 29, 13, 120, 5, 225,
|
||||
202, 3, 35, 225, 158, 92, 152, 73, 205, 107, 157, 224, 245,
|
||||
99, 194, 171, 156, 245, 247, 183, 165, 40, 62, 200, 110,
|
||||
29, 151, 206, 100, 175, 88, 36, 242, 90, 4, 82, 73, 250,
|
||||
140, 245, 217, 9, 153, 35, 242, 206, 78, 197, 121, 115, 15,
|
||||
80, 128, 101, 191, 240, 91, 151, 249, 62, 62, 244, 18, 3,
|
||||
17, 135, 222, 210, 93, 149, 123]),
|
||||
|
||||
192: new Uint8Array([126, 160, 166, 112, 227, 212, 106,
|
||||
186, 175, 70, 24, 28, 86, 149, 31, 154, 156, 190, 244, 132, 44, 61, 149,
|
||||
242, 105, 67, 17, 136, 7, 146, 153, 170, 200, 214, 142, 205, 170, 225,
|
||||
85, 44, 241, 159, 255, 234, 10, 13, 37, 48, 255, 21, 141, 176, 60, 117,
|
||||
73, 130, 247, 204, 144, 102, 167, 89, 203, 235, 229, 129, 122, 253, 124,
|
||||
179, 115, 118, 163, 157, 67, 141, 122, 146, 209, 11, 112, 5, 230, 117,
|
||||
123, 184, 243, 99, 83, 10, 31, 166, 96, 1, 121, 44, 10, 241, 24, 43,
|
||||
184, 187, 25, 239, 246, 176, 108, 230, 127, 25, 42, 67, 202, 140, 179,
|
||||
104, 159, 75, 103, 43, 248, 98, 166, 179, 67, 0, 163, 227, 84, 40, 129,
|
||||
227, 198, 205, 7, 156, 16, 185, 24, 166, 59, 218, 197, 114, 74, 34, 126,
|
||||
22, 226, 226, 85, 212, 69, 83, 163, 185, 68, 109, 182, 54, 209, 237, 96,
|
||||
184, 32, 53, 127, 175, 13, 146, 141, 115, 164, 184, 98, 245, 174, 223,
|
||||
46, 32, 167, 39, 103, 19, 210, 80, 131, 254, 103, 249, 247, 29, 120, 31,
|
||||
105, 241, 103, 169, 249, 93, 153, 74, 56, 53, 239, 157, 132, 236, 169,
|
||||
246, 242, 24, 113, 97, 128, 238, 152, 148, 31, 84, 8, 52, 105, 198, 116,
|
||||
103, 132, 48, 199, 23, 90, 24, 29, 63, 41, 117, 191, 57, 31, 209, 128,
|
||||
60, 119, 175, 84, 141, 177, 165, 169, 195, 35, 163, 105, 146, 157, 209,
|
||||
93, 149, 105, 160, 93, 231, 78, 201, 92, 235, 200, 89, 37, 50, 181, 30,
|
||||
213, 242, 59, 156, 219, 19, 158, 17, 224, 81, 108, 52, 87, 248, 101, 23,
|
||||
39, 107, 67, 151, 103, 230, 126, 202, 184, 118, 226, 18, 29, 93, 37, 208,
|
||||
40, 82, 113, 35, 157, 145, 152, 50, 253, 140, 47, 141, 192, 1, 148, 114,
|
||||
40, 10, 112, 79, 227, 16, 105, 247, 31, 49, 102, 195, 75, 183, 172, 254,
|
||||
188, 42, 89, 77, 38, 104, 1, 180, 106, 61, 71, 70, 35, 160, 103, 101,
|
||||
244, 26, 226, 37, 159, 155, 4, 107, 222, 219, 136, 37, 24, 246, 44, 23,
|
||||
44, 248, 132, 108, 59, 179, 99, 145, 132, 82, 53, 203, 111, 150, 55,
|
||||
123, 51, 214, 165, 108, 124, 179, 131, 174, 139, 224, 114, 96, 218, 181,
|
||||
243, 128, 198, 98, 115, 92, 95, 165, 23, 229, 108, 146, 14, 244, 162,
|
||||
37, 85, 201, 33, 44, 92, 106, 112, 185, 16, 189, 42, 114, 109, 59, 124,
|
||||
131, 16, 211, 31, 97, 29, 135, 61, 150, 75, 250, 207, 129, 38, 205, 187,
|
||||
186, 55, 207, 232, 24, 48, 232, 49, 226, 16, 12, 27, 70, 31, 124, 128,
|
||||
218, 100, 91, 200, 184, 78, 252, 100, 235, 62, 43, 69, 214, 163, 65, 14,
|
||||
44, 180]),
|
||||
|
||||
256: new Uint8Array([8, 97, 235, 113, 70, 32, 135, 131,
|
||||
210, 209, 124, 160, 255, 182, 9, 29, 125, 193, 27, 240, 129, 46, 2, 137,
|
||||
169, 142, 61, 7, 145, 54, 170, 207, 159, 111, 39, 95, 87, 63, 162, 27,
|
||||
6, 18, 219, 215, 116, 34, 90, 57, 114, 244, 102, 145, 67, 6, 51, 152,
|
||||
247, 165, 242, 116, 100, 219, 177, 72, 177, 17, 110, 67, 93, 219, 100,
|
||||
217, 20, 207, 89, 154, 45, 37, 105, 83, 67, 162, 140, 235, 129, 40, 177,
|
||||
202, 174, 54, 148, 55, 156, 193, 232, 249, 134, 163, 195, 51, 114, 116,
|
||||
65, 38, 73, 99, 96, 249, 224, 69, 17, 119, 186, 188, 181, 43, 78, 156,
|
||||
76, 138, 226, 63, 5, 248, 9, 94, 26, 1, 2, 235, 39, 174, 74, 47, 183,
|
||||
22, 40, 47, 47, 13, 100, 119, 12, 67, 178, 184, 56, 167, 238, 143, 13,
|
||||
44, 208, 185, 151, 108, 6, 17, 52, 122, 182, 210, 207, 42, 219, 37, 74,
|
||||
94, 126, 36, 249, 37, 32, 4, 218, 44, 238, 69, 56, 219, 31, 77, 173, 46,
|
||||
187, 103, 36, 112, 213, 252, 40, 87, 164, 240, 163, 159, 32, 129, 125,
|
||||
178, 108, 47, 28, 31, 36, 42, 115, 36, 14, 145, 195, 156, 191, 46, 163,
|
||||
249, 181, 31, 90, 73, 30, 72, 57, 223, 63, 60, 79, 140, 14, 117, 31,
|
||||
145, 222, 156, 121, 237, 32, 145, 143, 96, 12, 254, 35, 21, 21, 59, 168,
|
||||
171, 154, 217, 0, 59, 202, 175, 103, 214, 192, 175, 26, 18, 43, 54, 176,
|
||||
222, 75, 22, 7, 122, 253, 224, 145, 61, 42, 208, 73, 237, 84, 141, 209,
|
||||
213, 228, 46, 244, 59, 9, 68, 6, 35, 88, 189, 10, 62, 9, 85, 28, 44, 82,
|
||||
19, 153, 160, 178, 240, 56, 160, 244, 201, 173, 77, 61, 20, 227, 30,
|
||||
180, 167, 16, 105, 185, 193, 95, 207, 41, 23, 134, 78, 198, 182, 93, 24,
|
||||
89, 247, 231, 75, 233, 194, 137, 242, 114, 194, 190, 130, 138, 238, 94,
|
||||
137, 193, 194, 115, 137, 190, 207, 169, 83, 155, 14, 210, 160, 129, 195,
|
||||
161, 234, 221, 255, 114, 67, 98, 12, 93, 41, 65, 183, 244, 103, 247,
|
||||
101, 82, 246, 125, 87, 125, 78, 21, 186, 102, 205, 20, 40, 32, 201, 174,
|
||||
15, 52, 240, 217, 180, 162, 108, 6, 211, 41, 18, 135, 232, 184, 18, 188,
|
||||
169, 157, 190, 76, 166, 75, 176, 127, 39, 251, 22, 203, 153, 80, 49,
|
||||
241, 124, 137, 151, 123, 204, 43, 159, 190, 177, 196, 18, 117, 169, 46,
|
||||
152, 251, 45, 25, 164, 27, 145, 214, 228, 55, 15, 2, 131, 216, 80, 255,
|
||||
204, 175, 100, 59, 145, 15, 103, 40, 33, 45, 255, 200, 254, 172, 138,
|
||||
20, 58, 87, 182, 192, 148, 219, 41, 88, 230, 229, 70, 249])
|
||||
};
|
||||
|
||||
var keyLengths = [128, 192, 256];
|
||||
var tagLengths = [32, 64, 96, 104, 112, 120, 128];
|
||||
|
||||
// All the scenarios that should succeed, if the key has "encrypt" usage
|
||||
var passing = [];
|
||||
keyLengths.forEach(function(keyLength) {
|
||||
tagLengths.forEach(function(tagLength) {
|
||||
var byteCount = tagLength / 8;
|
||||
|
||||
var result = new Uint8Array(ciphertext[keyLength].byteLength + byteCount);
|
||||
result.set(ciphertext[keyLength], 0);
|
||||
result.set(tag[keyLength].slice(0, byteCount), ciphertext[keyLength].byteLength);
|
||||
passing.push({
|
||||
name: "AES-GCM " + keyLength.toString() + "-bit key, " + tagLength.toString() + "-bit tag",
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-GCM", iv: iv, additionalData: additionalData, tagLength: tagLength},
|
||||
plaintext: plaintext,
|
||||
result: result
|
||||
});
|
||||
|
||||
var noadresult = new Uint8Array(ciphertext[keyLength].byteLength + byteCount);
|
||||
noadresult.set(ciphertext[keyLength], 0);
|
||||
noadresult.set(tag_with_empty_ad[keyLength].slice(0, byteCount), ciphertext[keyLength].byteLength);
|
||||
passing.push({
|
||||
name: "AES-GCM " + keyLength.toString() + "-bit key, no additional data, " + tagLength.toString() + "-bit tag",
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-GCM", iv: iv, tagLength: tagLength},
|
||||
plaintext: plaintext,
|
||||
result: noadresult
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Scenarios that should fail because of a bad tag length, causing an OperationError
|
||||
var failing = [];
|
||||
keyLengths.forEach(function(keyLength) {
|
||||
// First, make some tests for bad tag lengths
|
||||
[24, 48, 72, 95, 129, 256].forEach(function(badTagLength) {
|
||||
failing.push({
|
||||
name: "AES-GCM " + keyLength.toString() + "-bit key, illegal tag length " + badTagLength.toString() + "-bits",
|
||||
keyBuffer: keyBytes[keyLength],
|
||||
key: null,
|
||||
algorithm: {name: "AES-GCM", iv: iv, additionalData: additionalData, tagLength: badTagLength},
|
||||
plaintext: plaintext,
|
||||
result: ciphertext[keyLength]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return {passing: passing, failing: failing, decryptionFailing: []};
|
||||
}
|
376
tests/wpt/web-platform-tests/WebCryptoAPI/encrypt_decrypt/rsa.js
Normal file
376
tests/wpt/web-platform-tests/WebCryptoAPI/encrypt_decrypt/rsa.js
Normal file
|
@ -0,0 +1,376 @@
|
|||
|
||||
function run_test() {
|
||||
var subtle = self.crypto.subtle; // Change to test prefixed implementations
|
||||
|
||||
// When are all these tests really done? When all the promises they use have resolved.
|
||||
var all_promises = [];
|
||||
|
||||
// Source file rsa_vectors.js provides the getTestVectors method
|
||||
// for the RSA-OAEP algorithm that drives these tests.
|
||||
var vectors = getTestVectors();
|
||||
var passingVectors = vectors.passing;
|
||||
var failingVectors = vectors.failing;
|
||||
|
||||
// Test decryption, first, because encryption tests rely on that working
|
||||
passingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"])
|
||||
.then(function(vectors) {
|
||||
// Get a one byte longer plaintext to encrypt
|
||||
if (!("ciphertext" in vector)) {
|
||||
return;
|
||||
}
|
||||
|
||||
promise_test(function(test) {
|
||||
return subtle.decrypt(vector.algorithm, vector.privateKey, vector.ciphertext)
|
||||
.then(function(plaintext) {
|
||||
assert_true(equalBuffers(plaintext, vector.plaintext, "Decryption works"));
|
||||
}, function(err) {
|
||||
assert_unreached("Decryption should not throw error " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
}, vector.name + " decryption");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " decryption");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Test decryption with an altered buffer
|
||||
passingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"])
|
||||
.then(function(vectors) {
|
||||
// Get a one byte longer plaintext to encrypt
|
||||
if (!("ciphertext" in vector)) {
|
||||
return;
|
||||
}
|
||||
|
||||
promise_test(function(test) {
|
||||
var ciphertext = copyBuffer(vector.ciphertext);
|
||||
var operation = subtle.decrypt(vector.algorithm, vector.privateKey, ciphertext)
|
||||
.then(function(plaintext) {
|
||||
assert_true(equalBuffers(plaintext, vector.plaintext, "Decryption works"));
|
||||
}, function(err) {
|
||||
assert_unreached("Decryption should not throw error " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
ciphertext[0] = 255 - ciphertext[0];
|
||||
return operation;
|
||||
}, vector.name + " decryption with altered ciphertext");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " decryption with altered ciphertext");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for failures due to using publicKey to decrypt.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
return subtle.decrypt(vector.algorithm, vector.publicKey, vector.ciphertext)
|
||||
.then(function(plaintext) {
|
||||
assert_unreached("Should have thrown error for using publicKey to decrypt in " + vector.name + ": " + err.message + "'");
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of " + err.message);
|
||||
});
|
||||
}, vector.name + " using publicKey to decrypt");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " using publicKey to decrypt");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
|
||||
// Check for failures due to no "decrypt" usage.
|
||||
passingVectors.forEach(function(originalVector) {
|
||||
var vector = Object.assign({}, originalVector);
|
||||
|
||||
var promise = importVectorKeys(vector, ["encrypt"], ["unwrapKey"])
|
||||
.then(function(vectors) {
|
||||
// Get a one byte longer plaintext to encrypt
|
||||
promise_test(function(test) {
|
||||
return subtle.decrypt(vector.algorithm, vector.publicKey, vector.ciphertext)
|
||||
.then(function(plaintext) {
|
||||
assert_unreached("Should have thrown error for no decrypt usage in " + vector.name + ": " + err.message + "'");
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of " + err.message);
|
||||
});
|
||||
}, vector.name + " no decrypt usage");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " no decrypt usage");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
|
||||
// Check for successful encryption even if plaintext is altered after call.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var plaintext = copyBuffer(vector.plaintext);
|
||||
var operation = subtle.encrypt(vector.algorithm, vector.publicKey, plaintext)
|
||||
.then(function(ciphertext) {
|
||||
assert_equals(ciphertext.byteLength * 8, vector.privateKey.algorithm.modulusLength, "Ciphertext length matches modulus length");
|
||||
// Can we get the original plaintext back via decrypt?
|
||||
return subtle.decrypt(vector.algorithm, vector.privateKey, ciphertext)
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, vector.plaintext), "Round trip returns original plaintext");
|
||||
return ciphertext;
|
||||
}, function(err) {
|
||||
assert_unreached("decrypt error for test " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
})
|
||||
.then(function(priorCiphertext) {
|
||||
// Will a second encrypt give us different ciphertext, as it should?
|
||||
return subtle.encrypt(vector.algorithm, vector.publicKey, vector.plaintext)
|
||||
.then(function(ciphertext) {
|
||||
assert_false(equalBuffers(priorCiphertext, ciphertext), "Two encrypts give different results")
|
||||
}, function(err) {
|
||||
assert_unreached("second time encrypt error for test " + vector.name + ": '" + err.message + "'");
|
||||
});
|
||||
}, function(err) {
|
||||
assert_unreached("decrypt error for test " + vector.name + ": '" + err.message + "'");
|
||||
});
|
||||
|
||||
plaintext[0] = 255 - plaintext[0];
|
||||
return operation;
|
||||
}, vector.name + " with altered plaintext");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " with altered plaintext");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for successful encryption.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
return subtle.encrypt(vector.algorithm, vector.publicKey, vector.plaintext)
|
||||
.then(function(ciphertext) {
|
||||
assert_equals(ciphertext.byteLength * 8, vector.privateKey.algorithm.modulusLength, "Ciphertext length matches modulus length");
|
||||
|
||||
// Can we get the original plaintext back via decrypt?
|
||||
return subtle.decrypt(vector.algorithm, vector.privateKey, ciphertext)
|
||||
.then(function(result) {
|
||||
assert_true(equalBuffers(result, vector.plaintext), "Round trip returns original plaintext");
|
||||
return ciphertext;
|
||||
}, function(err) {
|
||||
assert_unreached("decrypt error for test " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
})
|
||||
.then(function(priorCiphertext) {
|
||||
// Will a second encrypt give us different ciphertext, as it should?
|
||||
return subtle.encrypt(vector.algorithm, vector.publicKey, vector.plaintext)
|
||||
.then(function(ciphertext) {
|
||||
assert_false(equalBuffers(priorCiphertext, ciphertext), "Two encrypts give different results")
|
||||
}, function(err) {
|
||||
assert_unreached("second time encrypt error for test " + vector.name + ": '" + err.message + "'");
|
||||
});
|
||||
}, function(err) {
|
||||
assert_unreached("decrypt error for test " + vector.name + ": '" + err.message + "'");
|
||||
});
|
||||
}, vector.name);
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name);
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for failures due to too long plaintext.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"])
|
||||
.then(function(vectors) {
|
||||
// Get a one byte longer plaintext to encrypt
|
||||
var plaintext = new Uint8Array(vector.plaintext.byteLength + 1);
|
||||
plaintext.set(plaintext, 0);
|
||||
plaintext.set(new Uint8Array([32]), vector.plaintext.byteLength);
|
||||
promise_test(function(test) {
|
||||
return subtle.encrypt(vector.algorithm, vector.publicKey, plaintext)
|
||||
.then(function(ciphertext) {
|
||||
assert_unreached("Should have thrown error for too long plaintext in " + vector.name + ": " + err.message + "'");
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "OperationError", "Should throw OperationError instead of " + err.message);
|
||||
});
|
||||
}, vector.name + " too long plaintext");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " too long plaintext");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
|
||||
// Check for failures due to using privateKey to encrypt.
|
||||
passingVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
return subtle.encrypt(vector.algorithm, vector.privateKey, vector.plaintext)
|
||||
.then(function(ciphertext) {
|
||||
assert_unreached("Should have thrown error for using privateKey to encrypt in " + vector.name + ": " + err.message + "'");
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of " + err.message);
|
||||
});
|
||||
}, vector.name + " using privateKey to encrypt");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " using privateKey to encrypt");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
|
||||
// Check for failures due to no "encrypt usage".
|
||||
passingVectors.forEach(function(originalVector) {
|
||||
var vector = Object.assign({}, originalVector);
|
||||
|
||||
var promise = importVectorKeys(vector, [], ["decrypt"])
|
||||
.then(function(vectors) {
|
||||
// Get a one byte longer plaintext to encrypt
|
||||
promise_test(function(test) {
|
||||
return subtle.encrypt(vector.algorithm, vector.publicKey, vector.plaintext)
|
||||
.then(function(ciphertext) {
|
||||
assert_unreached("Should have thrown error for no encrypt usage in " + vector.name + ": " + err.message + "'");
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of " + err.message);
|
||||
});
|
||||
}, vector.name + " no encrypt usage");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested encryption
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " no encrypt usage");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
Promise.all(all_promises)
|
||||
.then(function() {done();})
|
||||
.catch(function() {done();})
|
||||
|
||||
// A test vector has all needed fields for encryption, EXCEPT that the
|
||||
// key field may be null. This function replaces that null with the Correct
|
||||
// CryptoKey object.
|
||||
//
|
||||
// Returns a Promise that yields an updated vector on success.
|
||||
function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) {
|
||||
var publicPromise, privatePromise;
|
||||
|
||||
if (vector.publicKey !== null) {
|
||||
publicPromise = new Promise(function(resolve, reject) {
|
||||
resolve(vector);
|
||||
});
|
||||
} else {
|
||||
publicPromise = subtle.importKey(vector.publicKeyFormat, vector.publicKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, publicKeyUsages)
|
||||
.then(function(key) {
|
||||
vector.publicKey = key;
|
||||
return vector;
|
||||
}); // Returns a copy of the sourceBuffer it is sent.
|
||||
function copyBuffer(sourceBuffer) {
|
||||
var source = new Uint8Array(sourceBuffer);
|
||||
var copy = new Uint8Array(sourceBuffer.byteLength)
|
||||
|
||||
for (var i=0; i<source.byteLength; i++) {
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (vector.privateKey !== null) {
|
||||
privatePromise = new Promise(function(resolve, reject) {
|
||||
resolve(vector);
|
||||
});
|
||||
} else {
|
||||
privatePromise = subtle.importKey(vector.privateKeyFormat, vector.privateKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, privateKeyUsages)
|
||||
.then(function(key) {
|
||||
vector.privateKey = key;
|
||||
return vector;
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all([publicPromise, privatePromise]);
|
||||
}
|
||||
|
||||
// Returns a copy of the sourceBuffer it is sent.
|
||||
function copyBuffer(sourceBuffer) {
|
||||
var source = new Uint8Array(sourceBuffer);
|
||||
var copy = new Uint8Array(sourceBuffer.byteLength)
|
||||
|
||||
for (var i=0; i<source.byteLength; i++) {
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
function equalBuffers(a, b) {
|
||||
if (a.byteLength !== b.byteLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var aBytes = new Uint8Array(a);
|
||||
var bBytes = new Uint8Array(b);
|
||||
|
||||
for (var i=0; i<a.byteLength; i++) {
|
||||
if (aBytes[i] !== bBytes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("rsa_vectors.js");
|
||||
importScripts("rsa.js");
|
||||
|
||||
run_test();
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<title>WebCryptoAPI: encrypt() Using AES-CBC</title>
|
||||
<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-encrypt">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="aes_cbc_vectors.js"></script>
|
||||
<script src="aes.js"></script>
|
||||
|
||||
<h1>encrypt Tests for AES-CBC</h1>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
run_test();
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<title>WebCryptoAPI: encrypt() Using AES-CTR</title>
|
||||
<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-encrypt">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="aes_ctr_vectors.js"></script>
|
||||
<script src="aes.js"></script>
|
||||
|
||||
<h1>encrypt Tests for AES-CTR</h1>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
run_test();
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<title>WebCryptoAPI: encrypt() Using AES-GCM</title>
|
||||
<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-encrypt">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="aes_gcm_vectors.js"></script>
|
||||
<script src="aes.js"></script>
|
||||
|
||||
<h1>encrypt Tests for AES-GCM</h1>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
run_test();
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<title>WebCryptoAPI: encrypt() Using RSA-OAEP</title>
|
||||
<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-encrypt">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="rsa_vectors.js"></script>
|
||||
<script src="rsa.js"></script>
|
||||
|
||||
<h1>encrypt Tests for RSA-OAEP</h1>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
run_test();
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue