mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
feat(ext/crypto): support AES-CTR encrypt/decrypt (#13177)
Fixes #13201.
This commit is contained in:
parent
a721c34c19
commit
9a42d65fc7
9 changed files with 378 additions and 77 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -557,6 +557,15 @@ dependencies = [
|
|||
"syn 1.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctr"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea"
|
||||
dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cty"
|
||||
version = "0.2.2"
|
||||
|
@ -775,6 +784,7 @@ dependencies = [
|
|||
"aes",
|
||||
"base64 0.13.0",
|
||||
"block-modes",
|
||||
"ctr",
|
||||
"deno_core",
|
||||
"deno_web",
|
||||
"elliptic-curve",
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { assert, assertEquals, assertRejects } from "./test_util.ts";
|
||||
import {
|
||||
assert,
|
||||
assertEquals,
|
||||
assertNotEquals,
|
||||
assertRejects,
|
||||
} from "./test_util.ts";
|
||||
|
||||
// https://github.com/denoland/deno/issues/11664
|
||||
Deno.test(async function testImportArrayBufferKey() {
|
||||
|
@ -608,6 +613,110 @@ Deno.test(async function testAesCbcEncryptDecrypt() {
|
|||
assertEquals(new Uint8Array(decrypted), new Uint8Array([1, 2, 3, 4, 5, 6]));
|
||||
});
|
||||
|
||||
Deno.test(async function testAesCtrEncryptDecrypt() {
|
||||
async function aesCtrRoundTrip(
|
||||
key: CryptoKey,
|
||||
counter: Uint8Array,
|
||||
length: number,
|
||||
plainText: Uint8Array,
|
||||
) {
|
||||
const cipherText = await crypto.subtle.encrypt(
|
||||
{
|
||||
name: "AES-CTR",
|
||||
counter,
|
||||
length,
|
||||
},
|
||||
key,
|
||||
plainText,
|
||||
);
|
||||
|
||||
assert(cipherText instanceof ArrayBuffer);
|
||||
assertEquals(cipherText.byteLength, plainText.byteLength);
|
||||
assertNotEquals(new Uint8Array(cipherText), plainText);
|
||||
|
||||
const decryptedText = await crypto.subtle.decrypt(
|
||||
{
|
||||
name: "AES-CTR",
|
||||
counter,
|
||||
length,
|
||||
},
|
||||
key,
|
||||
cipherText,
|
||||
);
|
||||
|
||||
assert(decryptedText instanceof ArrayBuffer);
|
||||
assertEquals(decryptedText.byteLength, plainText.byteLength);
|
||||
assertEquals(new Uint8Array(decryptedText), plainText);
|
||||
}
|
||||
for (const keySize of [128, 192, 256]) {
|
||||
const key = await crypto.subtle.generateKey(
|
||||
{ name: "AES-CTR", length: keySize },
|
||||
true,
|
||||
["encrypt", "decrypt"],
|
||||
) as CryptoKey;
|
||||
|
||||
// test normal operation
|
||||
for (const length of [128 /*, 64, 128 */]) {
|
||||
const counter = await crypto.getRandomValues(new Uint8Array(16));
|
||||
|
||||
await aesCtrRoundTrip(
|
||||
key,
|
||||
counter,
|
||||
length,
|
||||
new Uint8Array([1, 2, 3, 4, 5, 6]),
|
||||
);
|
||||
}
|
||||
|
||||
// test counter-wrapping
|
||||
for (const length of [32, 64, 128]) {
|
||||
const plaintext1 = await crypto.getRandomValues(new Uint8Array(32));
|
||||
const counter = new Uint8Array(16);
|
||||
|
||||
// fixed upper part
|
||||
for (let off = 0; off < 16 - (length / 8); ++off) {
|
||||
counter[off] = off;
|
||||
}
|
||||
const ciphertext1 = await crypto.subtle.encrypt(
|
||||
{
|
||||
name: "AES-CTR",
|
||||
counter,
|
||||
length,
|
||||
},
|
||||
key,
|
||||
plaintext1,
|
||||
);
|
||||
|
||||
// Set lower [length] counter bits to all '1's
|
||||
for (let off = 16 - (length / 8); off < 16; ++off) {
|
||||
counter[off] = 0xff;
|
||||
}
|
||||
|
||||
// = [ 1 block of 0x00 + plaintext1 ]
|
||||
const plaintext2 = new Uint8Array(48);
|
||||
plaintext2.set(plaintext1, 16);
|
||||
|
||||
const ciphertext2 = await crypto.subtle.encrypt(
|
||||
{
|
||||
name: "AES-CTR",
|
||||
counter,
|
||||
length,
|
||||
},
|
||||
key,
|
||||
plaintext2,
|
||||
);
|
||||
|
||||
// If counter wrapped, 2nd block of ciphertext2 should be equal to 1st block of ciphertext1
|
||||
// since ciphertext1 used counter = 0x00...00
|
||||
// and ciphertext2 used counter = 0xFF..FF which should wrap to 0x00..00 without affecting
|
||||
// higher bits
|
||||
assertEquals(
|
||||
new Uint8Array(ciphertext1),
|
||||
new Uint8Array(ciphertext2).slice(16),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// TODO(@littledivy): Enable WPT when we have importKey support
|
||||
Deno.test(async function testECDH() {
|
||||
const namedCurve = "P-256";
|
||||
|
|
|
@ -126,10 +126,12 @@
|
|||
"encrypt": {
|
||||
"RSA-OAEP": "RsaOaepParams",
|
||||
"AES-CBC": "AesCbcParams",
|
||||
"AES-CTR": "AesCtrParams",
|
||||
},
|
||||
"decrypt": {
|
||||
"RSA-OAEP": "RsaOaepParams",
|
||||
"AES-CBC": "AesCbcParams",
|
||||
"AES-CTR": "AesCtrParams",
|
||||
},
|
||||
"get key length": {
|
||||
"AES-CBC": "AesDerivedKeyParams",
|
||||
|
@ -605,6 +607,39 @@
|
|||
// 6.
|
||||
return plainText.buffer;
|
||||
}
|
||||
case "AES-CTR": {
|
||||
normalizedAlgorithm.counter = copyBuffer(normalizedAlgorithm.counter);
|
||||
|
||||
// 1.
|
||||
if (normalizedAlgorithm.counter.byteLength !== 16) {
|
||||
throw new DOMException(
|
||||
"Counter vector must be 16 bytes",
|
||||
"OperationError",
|
||||
);
|
||||
}
|
||||
|
||||
// 2.
|
||||
if (
|
||||
normalizedAlgorithm.length === 0 || normalizedAlgorithm.length > 128
|
||||
) {
|
||||
throw new DOMException(
|
||||
"Counter length must not be 0 or greater than 128",
|
||||
"OperationError",
|
||||
);
|
||||
}
|
||||
|
||||
// 3.
|
||||
const cipherText = await core.opAsync("op_crypto_decrypt", {
|
||||
key: keyData,
|
||||
algorithm: "AES-CTR",
|
||||
keyLength: key[_algorithm].length,
|
||||
counter: normalizedAlgorithm.counter,
|
||||
ctrLength: normalizedAlgorithm.length,
|
||||
}, data);
|
||||
|
||||
// 4.
|
||||
return cipherText.buffer;
|
||||
}
|
||||
default:
|
||||
throw new DOMException("Not implemented", "NotSupportedError");
|
||||
}
|
||||
|
@ -3431,6 +3466,39 @@
|
|||
// 4.
|
||||
return cipherText.buffer;
|
||||
}
|
||||
case "AES-CTR": {
|
||||
normalizedAlgorithm.counter = copyBuffer(normalizedAlgorithm.counter);
|
||||
|
||||
// 1.
|
||||
if (normalizedAlgorithm.counter.byteLength !== 16) {
|
||||
throw new DOMException(
|
||||
"Counter vector must be 16 bytes",
|
||||
"OperationError",
|
||||
);
|
||||
}
|
||||
|
||||
// 2.
|
||||
if (
|
||||
normalizedAlgorithm.length == 0 || normalizedAlgorithm.length > 128
|
||||
) {
|
||||
throw new DOMException(
|
||||
"Counter length must not be 0 or greater than 128",
|
||||
"OperationError",
|
||||
);
|
||||
}
|
||||
|
||||
// 3.
|
||||
const cipherText = await core.opAsync("op_crypto_encrypt", {
|
||||
key: keyData,
|
||||
algorithm: "AES-CTR",
|
||||
keyLength: key[_algorithm].length,
|
||||
counter: normalizedAlgorithm.counter,
|
||||
ctrLength: normalizedAlgorithm.length,
|
||||
}, data);
|
||||
|
||||
// 4.
|
||||
return cipherText.buffer;
|
||||
}
|
||||
default:
|
||||
throw new DOMException("Not implemented", "NotSupportedError");
|
||||
}
|
||||
|
|
|
@ -404,6 +404,24 @@
|
|||
webidl.converters.AesCbcParams = webidl
|
||||
.createDictionaryConverter("AesCbcParams", dictAesCbcParams);
|
||||
|
||||
const dictAesCtrParams = [
|
||||
...dictAlgorithm,
|
||||
{
|
||||
key: "counter",
|
||||
converter: webidl.converters["BufferSource"],
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: "length",
|
||||
converter: (V, opts) =>
|
||||
webidl.converters["unsigned short"](V, { ...opts, enforceRange: true }),
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
||||
webidl.converters.AesCtrParams = webidl
|
||||
.createDictionaryConverter("AesCtrParams", dictAesCtrParams);
|
||||
|
||||
webidl.converters.CryptoKey = webidl.createInterfaceConverter(
|
||||
"CryptoKey",
|
||||
CryptoKey,
|
||||
|
|
|
@ -17,6 +17,7 @@ path = "lib.rs"
|
|||
aes = "0.7.5"
|
||||
base64 = "0.13.0"
|
||||
block-modes = "0.8.1"
|
||||
ctr = "0.8.0"
|
||||
deno_core = { version = "0.112.0", path = "../../core" }
|
||||
deno_web = { version = "0.61.0", path = "../web" }
|
||||
elliptic-curve = { version = "0.10.6", features = ["std", "pem"] }
|
||||
|
|
|
@ -2,8 +2,18 @@ use std::cell::RefCell;
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::shared::*;
|
||||
use aes::BlockEncrypt;
|
||||
use aes::NewBlockCipher;
|
||||
use block_modes::BlockMode;
|
||||
use ctr::cipher::NewCipher;
|
||||
use ctr::cipher::StreamCipher;
|
||||
use ctr::flavors::Ctr128BE;
|
||||
use ctr::flavors::Ctr32BE;
|
||||
use ctr::flavors::Ctr64BE;
|
||||
use ctr::flavors::CtrFlavor;
|
||||
use ctr::Ctr;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
|
@ -39,6 +49,13 @@ pub enum DecryptAlgorithm {
|
|||
iv: Vec<u8>,
|
||||
length: usize,
|
||||
},
|
||||
#[serde(rename = "AES-CTR", rename_all = "camelCase")]
|
||||
AesCtr {
|
||||
#[serde(with = "serde_bytes")]
|
||||
counter: Vec<u8>,
|
||||
ctr_length: usize,
|
||||
key_length: usize,
|
||||
},
|
||||
}
|
||||
|
||||
pub async fn op_crypto_decrypt(
|
||||
|
@ -54,6 +71,11 @@ pub async fn op_crypto_decrypt(
|
|||
DecryptAlgorithm::AesCbc { iv, length } => {
|
||||
decrypt_aes_cbc(key, length, iv, &data)
|
||||
}
|
||||
DecryptAlgorithm::AesCtr {
|
||||
counter,
|
||||
ctr_length,
|
||||
key_length,
|
||||
} => decrypt_aes_ctr(key, key_length, &counter, ctr_length, &data),
|
||||
};
|
||||
let buf = tokio::task::spawn_blocking(fun).await.unwrap()?;
|
||||
Ok(buf.into())
|
||||
|
@ -153,3 +175,56 @@ fn decrypt_aes_cbc(
|
|||
// 6.
|
||||
Ok(plaintext)
|
||||
}
|
||||
|
||||
fn decrypt_aes_ctr_gen<B, F>(
|
||||
key: &[u8],
|
||||
counter: &[u8],
|
||||
data: &[u8],
|
||||
) -> Result<Vec<u8>, AnyError>
|
||||
where
|
||||
B: BlockEncrypt + NewBlockCipher,
|
||||
F: CtrFlavor<B::BlockSize>,
|
||||
{
|
||||
let mut cipher = Ctr::<B, F>::new(key.into(), counter.into());
|
||||
|
||||
let mut plaintext = data.to_vec();
|
||||
cipher
|
||||
.try_apply_keystream(&mut plaintext)
|
||||
.map_err(|_| operation_error("tried to decrypt too much data"))?;
|
||||
|
||||
Ok(plaintext)
|
||||
}
|
||||
|
||||
fn decrypt_aes_ctr(
|
||||
key: RawKeyData,
|
||||
key_length: usize,
|
||||
counter: &[u8],
|
||||
ctr_length: usize,
|
||||
data: &[u8],
|
||||
) -> Result<Vec<u8>, deno_core::anyhow::Error> {
|
||||
let key = key.as_secret_key()?;
|
||||
|
||||
match ctr_length {
|
||||
32 => match key_length {
|
||||
128 => decrypt_aes_ctr_gen::<aes::Aes128, Ctr32BE>(key, counter, data),
|
||||
192 => decrypt_aes_ctr_gen::<aes::Aes192, Ctr32BE>(key, counter, data),
|
||||
256 => decrypt_aes_ctr_gen::<aes::Aes256, Ctr32BE>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
64 => match key_length {
|
||||
128 => decrypt_aes_ctr_gen::<aes::Aes128, Ctr64BE>(key, counter, data),
|
||||
192 => decrypt_aes_ctr_gen::<aes::Aes192, Ctr64BE>(key, counter, data),
|
||||
256 => decrypt_aes_ctr_gen::<aes::Aes256, Ctr64BE>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
128 => match key_length {
|
||||
128 => decrypt_aes_ctr_gen::<aes::Aes128, Ctr128BE>(key, counter, data),
|
||||
192 => decrypt_aes_ctr_gen::<aes::Aes192, Ctr128BE>(key, counter, data),
|
||||
256 => decrypt_aes_ctr_gen::<aes::Aes256, Ctr128BE>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
_ => Err(type_error(
|
||||
"invalid counter length. Currently supported 32/64/128 bits",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,19 @@ use std::cell::RefCell;
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::shared::*;
|
||||
|
||||
use aes::cipher::NewCipher;
|
||||
use aes::BlockEncrypt;
|
||||
use aes::NewBlockCipher;
|
||||
use ctr::Ctr;
|
||||
|
||||
use block_modes::BlockMode;
|
||||
use ctr::cipher::StreamCipher;
|
||||
use ctr::flavors::Ctr128BE;
|
||||
|
||||
use ctr::flavors::Ctr32BE;
|
||||
use ctr::flavors::Ctr64BE;
|
||||
use ctr::flavors::CtrFlavor;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::OpState;
|
||||
|
@ -41,6 +53,13 @@ pub enum EncryptAlgorithm {
|
|||
iv: Vec<u8>,
|
||||
length: usize,
|
||||
},
|
||||
#[serde(rename = "AES-CTR", rename_all = "camelCase")]
|
||||
AesCtr {
|
||||
#[serde(with = "serde_bytes")]
|
||||
counter: Vec<u8>,
|
||||
ctr_length: usize,
|
||||
key_length: usize,
|
||||
},
|
||||
}
|
||||
pub async fn op_crypto_encrypt(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
|
@ -55,6 +74,11 @@ pub async fn op_crypto_encrypt(
|
|||
EncryptAlgorithm::AesCbc { iv, length } => {
|
||||
encrypt_aes_cbc(key, length, iv, &data)
|
||||
}
|
||||
EncryptAlgorithm::AesCtr {
|
||||
counter,
|
||||
ctr_length,
|
||||
key_length,
|
||||
} => encrypt_aes_ctr(key, key_length, &counter, ctr_length, &data),
|
||||
};
|
||||
let buf = tokio::task::spawn_blocking(fun).await.unwrap()?;
|
||||
Ok(buf.into())
|
||||
|
@ -136,3 +160,56 @@ fn encrypt_aes_cbc(
|
|||
};
|
||||
Ok(ciphertext)
|
||||
}
|
||||
|
||||
fn encrypt_aes_ctr_gen<B, F>(
|
||||
key: &[u8],
|
||||
counter: &[u8],
|
||||
data: &[u8],
|
||||
) -> Result<Vec<u8>, AnyError>
|
||||
where
|
||||
B: BlockEncrypt + NewBlockCipher,
|
||||
F: CtrFlavor<B::BlockSize>,
|
||||
{
|
||||
let mut cipher = Ctr::<B, F>::new(key.into(), counter.into());
|
||||
|
||||
let mut ciphertext = data.to_vec();
|
||||
cipher
|
||||
.try_apply_keystream(&mut ciphertext)
|
||||
.map_err(|_| operation_error("tried to encrypt too much data"))?;
|
||||
|
||||
Ok(ciphertext)
|
||||
}
|
||||
|
||||
fn encrypt_aes_ctr(
|
||||
key: RawKeyData,
|
||||
key_length: usize,
|
||||
counter: &[u8],
|
||||
ctr_length: usize,
|
||||
data: &[u8],
|
||||
) -> Result<Vec<u8>, AnyError> {
|
||||
let key = key.as_secret_key()?;
|
||||
|
||||
match ctr_length {
|
||||
32 => match key_length {
|
||||
128 => encrypt_aes_ctr_gen::<aes::Aes128, Ctr32BE>(key, counter, data),
|
||||
192 => encrypt_aes_ctr_gen::<aes::Aes192, Ctr32BE>(key, counter, data),
|
||||
256 => encrypt_aes_ctr_gen::<aes::Aes256, Ctr32BE>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
64 => match key_length {
|
||||
128 => encrypt_aes_ctr_gen::<aes::Aes128, Ctr64BE>(key, counter, data),
|
||||
192 => encrypt_aes_ctr_gen::<aes::Aes192, Ctr64BE>(key, counter, data),
|
||||
256 => encrypt_aes_ctr_gen::<aes::Aes256, Ctr64BE>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
128 => match key_length {
|
||||
128 => encrypt_aes_ctr_gen::<aes::Aes128, Ctr128BE>(key, counter, data),
|
||||
192 => encrypt_aes_ctr_gen::<aes::Aes192, Ctr128BE>(key, counter, data),
|
||||
256 => encrypt_aes_ctr_gen::<aes::Aes256, Ctr128BE>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
_ => Err(type_error(
|
||||
"invalid counter length. Currently supported 32/64/128 bits",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
|
17
ext/crypto/lib.deno_crypto.d.ts
vendored
17
ext/crypto/lib.deno_crypto.d.ts
vendored
|
@ -62,6 +62,11 @@ interface AesCbcParams extends Algorithm {
|
|||
iv: BufferSource;
|
||||
}
|
||||
|
||||
interface AesCtrParams extends Algorithm {
|
||||
counter: BufferSource;
|
||||
length: number;
|
||||
}
|
||||
|
||||
interface HmacKeyGenParams extends Algorithm {
|
||||
hash: HashAlgorithmIdentifier;
|
||||
length?: number;
|
||||
|
@ -239,12 +244,20 @@ interface SubtleCrypto {
|
|||
data: BufferSource,
|
||||
): Promise<ArrayBuffer>;
|
||||
encrypt(
|
||||
algorithm: AlgorithmIdentifier | RsaOaepParams | AesCbcParams,
|
||||
algorithm:
|
||||
| AlgorithmIdentifier
|
||||
| RsaOaepParams
|
||||
| AesCbcParams
|
||||
| AesCtrParams,
|
||||
key: CryptoKey,
|
||||
data: BufferSource,
|
||||
): Promise<ArrayBuffer>;
|
||||
decrypt(
|
||||
algorithm: AlgorithmIdentifier | RsaOaepParams | AesCbcParams,
|
||||
algorithm:
|
||||
| AlgorithmIdentifier
|
||||
| RsaOaepParams
|
||||
| AesCbcParams
|
||||
| AesCtrParams,
|
||||
key: CryptoKey,
|
||||
data: BufferSource,
|
||||
): Promise<ArrayBuffer>;
|
||||
|
|
|
@ -39,80 +39,10 @@
|
|||
"digest.https.any.worker.html": true
|
||||
},
|
||||
"encrypt_decrypt": {
|
||||
"aes_cbc.https.any.html": [
|
||||
"AES-CBC 128-bit key with mismatched key and algorithm",
|
||||
"AES-CBC 192-bit key with mismatched key and algorithm",
|
||||
"AES-CBC 256-bit key with mismatched key and algorithm"
|
||||
],
|
||||
"aes_cbc.https.any.worker.html": [
|
||||
"AES-CBC 128-bit key with mismatched key and algorithm",
|
||||
"AES-CBC 192-bit key with mismatched key and algorithm",
|
||||
"AES-CBC 256-bit key with mismatched key and algorithm"
|
||||
],
|
||||
"aes_ctr.https.any.html": [
|
||||
"AES-CTR 128-bit key",
|
||||
"AES-CTR 192-bit key",
|
||||
"AES-CTR 256-bit key",
|
||||
"AES-CTR 128-bit key with altered plaintext",
|
||||
"AES-CTR 192-bit key with altered plaintext",
|
||||
"AES-CTR 256-bit key with altered plaintext",
|
||||
"AES-CTR 128-bit key decryption",
|
||||
"AES-CTR 192-bit key decryption",
|
||||
"AES-CTR 256-bit key decryption",
|
||||
"AES-CTR 128-bit key decryption with altered ciphertext",
|
||||
"AES-CTR 192-bit key decryption with altered ciphertext",
|
||||
"AES-CTR 256-bit key decryption with altered ciphertext",
|
||||
"AES-CTR 128-bit key without encrypt usage",
|
||||
"AES-CTR 192-bit key without encrypt usage",
|
||||
"AES-CTR 256-bit key without encrypt usage",
|
||||
"AES-CTR 128-bit key without decrypt usage",
|
||||
"AES-CTR 192-bit key without decrypt usage",
|
||||
"AES-CTR 256-bit key without decrypt usage",
|
||||
"AES-CTR 128-bit key, 0-bit counter",
|
||||
"AES-CTR 128-bit key, 129-bit counter",
|
||||
"AES-CTR 192-bit key, 0-bit counter",
|
||||
"AES-CTR 192-bit key, 129-bit counter",
|
||||
"AES-CTR 256-bit key, 0-bit counter",
|
||||
"AES-CTR 256-bit key, 129-bit counter",
|
||||
"AES-CTR 128-bit key, 0-bit counter decryption",
|
||||
"AES-CTR 128-bit key, 129-bit counter decryption",
|
||||
"AES-CTR 192-bit key, 0-bit counter decryption",
|
||||
"AES-CTR 192-bit key, 129-bit counter decryption",
|
||||
"AES-CTR 256-bit key, 0-bit counter decryption",
|
||||
"AES-CTR 256-bit key, 129-bit counter decryption"
|
||||
],
|
||||
"aes_ctr.https.any.worker.html": [
|
||||
"AES-CTR 128-bit key",
|
||||
"AES-CTR 192-bit key",
|
||||
"AES-CTR 256-bit key",
|
||||
"AES-CTR 128-bit key with altered plaintext",
|
||||
"AES-CTR 192-bit key with altered plaintext",
|
||||
"AES-CTR 256-bit key with altered plaintext",
|
||||
"AES-CTR 128-bit key decryption",
|
||||
"AES-CTR 192-bit key decryption",
|
||||
"AES-CTR 256-bit key decryption",
|
||||
"AES-CTR 128-bit key decryption with altered ciphertext",
|
||||
"AES-CTR 192-bit key decryption with altered ciphertext",
|
||||
"AES-CTR 256-bit key decryption with altered ciphertext",
|
||||
"AES-CTR 128-bit key without encrypt usage",
|
||||
"AES-CTR 192-bit key without encrypt usage",
|
||||
"AES-CTR 256-bit key without encrypt usage",
|
||||
"AES-CTR 128-bit key without decrypt usage",
|
||||
"AES-CTR 192-bit key without decrypt usage",
|
||||
"AES-CTR 256-bit key without decrypt usage",
|
||||
"AES-CTR 128-bit key, 0-bit counter",
|
||||
"AES-CTR 128-bit key, 129-bit counter",
|
||||
"AES-CTR 192-bit key, 0-bit counter",
|
||||
"AES-CTR 192-bit key, 129-bit counter",
|
||||
"AES-CTR 256-bit key, 0-bit counter",
|
||||
"AES-CTR 256-bit key, 129-bit counter",
|
||||
"AES-CTR 128-bit key, 0-bit counter decryption",
|
||||
"AES-CTR 128-bit key, 129-bit counter decryption",
|
||||
"AES-CTR 192-bit key, 0-bit counter decryption",
|
||||
"AES-CTR 192-bit key, 129-bit counter decryption",
|
||||
"AES-CTR 256-bit key, 0-bit counter decryption",
|
||||
"AES-CTR 256-bit key, 129-bit counter decryption"
|
||||
],
|
||||
"aes_cbc.https.any.html": true,
|
||||
"aes_cbc.https.any.worker.html": true,
|
||||
"aes_ctr.https.any.html": true,
|
||||
"aes_ctr.https.any.worker.html": true,
|
||||
"aes_gcm.https.any.html": [
|
||||
"AES-GCM 128-bit key, 32-bit tag",
|
||||
"AES-GCM 128-bit key, no additional data, 32-bit tag",
|
||||
|
|
Loading…
Add table
Reference in a new issue